I've created a header file "foo.h" as well as an source file "bar.c" but can't seem to import bar.c into foo.h.
Is this possible? If so, could someone please point me in the right direction?
You've got it backwards... .h files exist to tell other programs what a .c file contains. The .c implements the things listed in the header.
Then, when a different program wants to use some of the stuff you implemented, they #include your header. When it compiles, another program called the linker is also run. This connects the functions from the header you used to their implementations.
Basically, Importing source files is something that should be avoided, although some compilers allow it.
Regarding the data types, it makes perfectly sense to declare them in the header file.
Related
I am trying to understand the IPv6-over-BLE UDP-client demo example which is present in examples/cc26xx/cc26xx-ble-client-demo, the code has following header files:
#include "contiki.h"
#include "contiki-lib.h"
#include "contiki-net.h"
#define DEBUG DEBUG_FULL
#include "net/ip/uip-debug.h"
#include "net/ip/uiplib.h"
#include "net/ipv6/uip-icmp6.h"
I just want to know the locations of these header files in the Contiki file system as the code for the main implementation of the BLE connection is under cpu/cc26xx-cc13xx/rf-core/*.[ch] and cpu/cc26xx-cc13xx/net/*.[ch]. I want to understand how the example code can use the methods present in files at different locations.
So you need to understand how an application is build.
All executable code is defined in C files and translated into machine code. Having said this, there might be modules written in other languages, the C runtime most probably has some assembler sources. We can call these "translation units" because they are each translated separately on their own.
The header files just contain declarations of objects implemented in those translation units. Header files can combine declarations of several units or deliberately leave out some declarations.
If you compile one of your own sources which includes a header file there will be no code of the referenced objects in your resulting object file.
At the link stage the linker combines all object modules of your program, resolving references between all of them. That means if you have a call in one unit to a method in another module, that call will receive the correct address.
There are still unsatisfied references left, in particular those to library methods that were declared in those header files. The linker searches through the default and the explicitely given libraries to look for the methods. If it finds one it will get added to the code and the call will receive its address.
This is it really very short. Please search for a broader description in the web, you'll find a lot of them.
To answer your explicit question: "How can the example code use the methods present in files at different locations?"
The linker adds the machine code of these methods to the machine code of your modules. The location of their source code is irrelevant. The linker knows the location of the standard libraries. If you use additional libraries, add them (and their path, if needed) to the command line.
If you have any further questions, edit your question, please.
contiki.h, contiki-lib.h, contiki-net.h: These files are in contiki/core/ folder.
uip-debug.h: contiki/core/net/ip
uiplib.h: contiki/core/net/ip
uip-icmp6.h: contiki/core/net/ipv6/
Please find the answer below.
https://github.com/contiki-os/contiki/tree/master/core
"contiki.h"
"contiki-lib.h"
"contiki-net.h"
https://github.com/contiki-os/contiki/blob/master/core/net/ip/uip-debug.h
You can find the header files in the Contiki in the same respective locations.
I'm going rounds with the compiler right now, and I want to make sure the problem isn't a fundamental misunderstanding of how header files. If I include a header file, and that header file has includes in it (like <stdbool.h> or <stdio.h>, etc...), there shouldn't be any issue on the dependent C file, right? The preprocessor should just insert the assembled code accordingly when I call my makefile, by my understanding. Am I mistaken?
To reiterate:
Say I have a main.c with prototype.h.
prototype.h has in it all of my usual includes for libraries and what-not.
I have a couple other C files (secondary.c and tertiary.c, for instance), both of which need the usual libraries, as well, and may or may not need some of the prototypes and also have their own header files.
All I'd need to do is include prototype.h in each of the C files, correct?
Also, in that instance, if I were making .o file using the -c flag of gcc in my makefile, would I need to update the dependency in the target of the makefile?
I thought I had a solid handle on this when I started, but now I'm thoroughly confused.
That is questions with multiple answers.
In simple case you only include headers if they are used in .c file. Headers are dependencies for compilation so for Make you just put it in the same bucket where .c files using those.
For big projects to speedup compilation you may use what called 'precompiled header'. You must include the same header file into every source file, compiler will only process that header once. That is very useful when headers are complicated (e.g. boost library)
So currently in my programming I now have a fairly large range of functions I have created and stored in separate C files that I use quite frequently from project to project.
My question is what is the simplest, most effective way to implement them into other projects? Currently I just make a header file for each new project that has the function prototypes for all the custom functions I want to use.
I then have every C file in the project include this "master" header. In this header I also include header files that each C file utilizes, so every C file has one header; let's just call it master.h.
I feel like I am doing this completely wrong. Should I be making header files for each C file and including them into a master header file? or should I just create header files per C file and include them as needed? If I do that how will everything still be linked together?
What is the best way to go about using header files in projects?
Do not have a header file including other header files. Let the .c file do that - makes compilation quicker.
Use forward declarations. Makes recompilation quicker as it does not need to open up other files and if any simple change the make command will spend ages compiling lots of stuff.
Group functions together in both a header file and the corresponding .c file if they logically fit together. For static libraries the linker picks out the appropriate bits. For dynamic libraries they are loaded at run time (hence can be used by other binaries) if not currently in memory.
Do not have a master.h. Just make libraries contain functions that are related (e.g. math function, input/output functions etc). The various projects can pick 'n' chose what they require.
I recommend against having a master.h file, as your whole project ends up being too coupled. Every time you change master.h all your source files need to be recompiled, which significantly slows down the build process. Instead, try to create .h files with related functions. The C library is a good inspiration for this: stdlib.h, math.h etc.
In order to use these headers, you should include them in each .c, just like you would with the standard C headers:
#include <math.h>
#include <stdio.h>
As for linking, this is a totally different subject. If most of your functions are inlined, you do not have to worry about linking. Otherwise, you should define them in .c files which are named similarly to your headers (e.g., utils.c for utils.h etc.)
Create a header file for all the .c files. Group the similar functions in a .c file. Dont forget to add header guard in each header files.
For example consider a header file one.h, it should contain the below header guards.
#ifndef ONE_H
#define ONE_H
//give your function prototypes here.
#endif //ONE_H
Header guard will be useful to avoid double includes.
I need to remove a bunch of function prototypes from several .h files, and I was wondering if there is some kind of bash script/program to look for the prototypes that are not in the .c file and automatically remove them.
This is really useful for source code cleaning purposes when you have a big project and you did not keep track of all the changes.
Note that the it does not have anything to do with the binary, I want to remove them from the code.
I don't know of any program that fits your need exactly; but with some neat lateral thinking, you arrive at cproto, which sort of does what you need. Just remove the current header file, run cproto to get a new one only containing the relevant prototypes, and put in whatever macros and typedefs you need from your preamble.
You could use makeheaders to generate header files with the correct list of prototypes in and either use those headers, or cut'n'paste the definitions to replace the ones in your existing headers
You might be able to implement this loop in your favorite scripting language:
For each .c file, find the corresponding .h file. Make all the prototypes in the .h file static. Compile the .c file. Clear up compiler errors regarding undefined static declarations. Revert the remaining prototypes.
This does not exactly what you want, but might come close. If you use doxygen you can have it generate a whole bunch of lists and also visualize them as graphs. One of them is a called by relation for functions and the other one a included by relation for files.
You don't need to put doxygen special comments in, you may just use it to be structural information about your project.
I tried both cproto and makeheaders.
The first one works as expected: I've created the header files, then I copied the typedef definitions, includes to other header files (important!) and so on and everything worked fine.
makeheaders is a little bit more complicated/clever, as it will create .h following the includes in the .c, so no other includes in the .h are required.
I'm used to doing all my coding in one C file. However, I'm working on a project large enough that it becomes impractical to do so. I've been #including them together but I've run into cases where I'm #including some files multiple times, etc. I've heard of .h files, but I'm not sure what their function is (or why having 2 files is better than 1).
What strategies should I use for organizing my code? Is it possible to separate "public" functions from "private" ones for a particular file?
This question precipitated my inquiry. The tea.h file makes no reference to the tea.c file. Does the compiler "know" that every .h file has a corresponding .c file?
You should regard .h files as interface files of your .c file. Every .c file represents a module with a certain amount of functionality. If functions in a .c file are used by other modules (i.e. other .c files) put the function prototype in the .h interface file. By including the interface file in your original modules .c file and every other .c file you need the function in, you make this function available to other modules.
If you only need a function in a certain .c file (not in any other module), declare its scope static. This means it can only be called from within the c file it is defined in.
Same goes for variables that are used across multiple modules. They should go in the header file and there they have to marked with the keyword 'extern'. Note: For functions the keyword 'extern' is optional. Functions are always considered 'extern'.
The inclusion guards in header files help to not include the same header file multiple times.
For example:
Module1.c:
#include "Module1.h"
static void MyLocalFunction(void);
static unsigned int MyLocalVariable;
unsigned int MyExternVariable;
void MyExternFunction(void)
{
MyLocalVariable = 1u;
/* Do something */
MyLocalFunction();
}
static void MyLocalFunction(void)
{
/* Do something */
MyExternVariable = 2u;
}
Module1.h:
#ifndef __MODULE1.H
#define __MODULE1.H
extern unsigned int MyExternVariable;
void MyExternFunction(void);
#endif
Module2.c
#include "Module.1.h"
static void MyLocalFunction(void);
static void MyLocalFunction(void)
{
MyExternVariable = 1u;
MyExternFunction();
}
Try to make each .c focus on a particular area of functionality. Use the corresponding .h file to declare those functions.
Each .h file should have a 'header' guard around it's content. For example:
#ifndef ACCOUNTS_H
#define ACCOUNTS_H
....
#endif
That way you can include "accounts.h" as many times as you want, and the first time it's seen in a particular compilation unit will be the only one that actually pulls in its content.
Compiler
You can see an example of a C 'module' at this topic - Note that there are two files - the header tea.h, and the code tea.c. You declare all the public defines, variables, and function prototypes that you want other programs to access in the header. In your main project you'll #include and that code can now access the functions and variables of the tea module that are mentioned in the header.
It gets a little more complex after that. If you're using Visual Studio and many other IDEs that manage your build for you, then ignore this part - they take care of compiling and linking objects.
Linker
When you compile two separate C files the compiler produces individual object files - so main.c becomes main.o, and tea.c becomes tea.o. The linker's job is to look at all the object files (your main.o and tea.o), and match up the references - so when you call a tea function in main, the linker modifies that call so it actually does call the right function in tea. The linker produces the executable file.
There is a great tutorial that goes into more depth on this subject, including scope and other issue you'll run into.
Good luck!
-Adam
A couple of simple rules to start:
Put those declarations that you want to make "public" into the header file for the C implementation file you are creating.
Only #include header files in the C file that are needed to implement the C file.
include header files in a header file only if required for the declarations within that header file.
Use the include guard method described by Andrew OR use #pragma once if the compiler supports it (which does the same thing -- sometimes more efficiently)
To answer your additional question:
This
question precipitated my inquiry. The
tea.h file makes no reference to the
tea.c file. Does the compiler "know"
that every .h file has a corresponding
.c file?
The compiler is not primarily concerned with header files. Each invocation of the compiler compiles a source (.c) file into an object (.o) file. Behind the scenes (i.e. in the make file or project file) a command line equivalent to this is being generated:
compiler --options tea.c
The source file #includes all the header files for the resources it references, which is how the compiler finds header files.
(I'm glossing over some details here. There is a lot to learn about building C projects.)
As well as the answers supplied above, one small advantage of splinting up your code into modules (separate files) is that if you have to have any global variables, you can limit their scope to a single module by the use of the key word 'static'. (You could also apply this to functions). Note that this use of 'static' is different from its use inside a function.
Your question makes it clear that you haven't really done much serious development. The usual case is that your code will generally be far too large to fit into one file. A good rule is that you should split the functionality into logical units (.c files) and each file should contain no more than what you can easily hold in your head at one time.
A given software product then generally includes the output from many different .c files. How this is normally done is that the compiler produces a number of object files (in unix systems ".o" files, VC generates .obj files). It is the purpose of the "linker" to compose these object files into the output (either a shared library or executable).
Generally your implementation (.c) files contain actual executable code, while the header files (.h) have the declarations of the public functions in those implementation files. You can quite easily have more header files than there are implementation files, and sometimes header files can contain inline code as well.
It is generally quite unusual for implementation files to include each other. A good practice is to ensure that each implementation file separates its concerns from the other files.
I would recommend you download and look at the source for the linux kernel. It is quite massive for a C program, but well organised into separate areas of functionality.
The .h files should be used to define the prototypes for your functions. This is necessary so you can include the prototypes that you need in your C-file without declaring every function that you need all in one file.
For instance, when you #include <stdio.h>, this provides the prototypes for printf and other IO functions. The symbols for these functions are normally loaded by the compiler by default. You can look at the system's .h files under /usr/include if you're interested in the normal idioms involved with these files.
If you're only writing trivial applications with not many functions, it's not really necessary to modularize everything out into logical groupings of procedures. However, if you have the need to develop a large system, then you'll need to pay some consideration as to where to define each of your functions.