Let's suppose that I write some functions in a file, that we'll call foo.c.
This is foo.c:
int d;
typedef int bar;
int foo(int a, int b){
...
}
void boo(){
...
}
char *test(){
...
}
Now, boo is a function used only inside foo.c, while foo(), test(), d, and Bool will need to be able to get called inside other files.
In order to do that, I know that I have to create a foo.h file and write it like this:
extern int d;
extern typedef int bar;
int foo(int a, int b);
char *test();
then #include "foo.h" in the foo.c file, and whenever I want to use the types and functions defined in foo.c, I have to include both foo.hand foo.cin the file in which I wanna use foo.c functions and types.
So foo.c in the end would look like this:
#include "foo.h"
int d;
typedef int bar;
int foo(int a, int b){
...
}
void boo(){
...
}
char *test(){
...
}
Here are my questions.
Q1. Is this how you actually do it? Since foo.h is already included in foo.c, wouldn't it be sufficient to include only foo.c in the file in which I want to use its functions? Can't I just directly define the functions inside of the foo.c file, not using the foo.h file at all?
Q2. Do you actually have to put the extern in front of typedefs in the foo.h file?
Q3. Let's say that in foo.c I use some standard C libraries like string.h and math.h . Where should I include them? Directly in the foo.c file, in the foo.h file or in both? Are #ifndef instructions necessary? If so, how do you use them correctly?
Q4. After writing the foo.c and foo.h file, am I all ready to go? Like, I don't need to compile them or anything, right? I can just #include them wherever I need just like that?
Q5. Somewhere else I've read that if I want to use a custom library these are the steps that I need to follow:
define the interface (foo.h)
write foo.c #include ing foo.h
creating an object file like this gcc -o foo.o -c foo.c
including foo.h in the program in which I want to use foo.c functions
linking the object file like this gcc my_proj.c foo.o
Are these steps actually necessary? Because I haven't seen them mentioned anywhere else. Why do I only need to include foo.h in the file in which I want to use foo.c functions? What exactly is an object file?
Thanks for your time and sorry if this is a bit lengthy
Q1. Is this how you actually do it? Since foo.h is already included in foo.c, wouldn't it be sufficient to include only foo.c in the file in which I want to use its functions?
You just don't include .c files. In your case, foo.c and the other files are separate compilation units which get linked together in the end.
Q2. Do you actually have to put the external in front of typedefs in the foo.h file?
No, typedefs don't need extern.
Q3. Let's say that in foo.c I use some standard C libraries like string.h and math.h . Where should I include them? Directly in the foo.c file, in the foo.h file or in both? Are #ifndef instructions necessary? If so, how do you use them correctly?
If you need these files in the .h as well, you include them there (e. g. for types used in function prototypes). If you need them only in your .c, include them there.
Q4. After writing the foo.c and foo.h file, am I all ready to go? Like, I don't need to compile them or anything, right? I can just #include them wherever I need just like that?
You can compile them in order to get something callable. If you don't compile your program, you cannot use it. Or do I understand you wrong?
Q5. Somewhere else I've read that if I want to use a custom library these are the steps that I need to follow:
[snip]
Indeed, this is one way to go. The steps 1, 2 and 4 cannot be omitted for obvious reasons. But you can execute step 3 and 5 together by doing
gcc my_proj.c foo.c
This compiles the given files and then links them together in one call.
Why do I only need to include foo.h in the file in which I want to use foo.c functions?
That's because the resulting object file contains information for the linker about which function it needs from other object files.
What exactly is an object file?
It is what results from compiling one source file. If you link several object files together, you get a running executable.
In other words: An object file is the compiled version of a source file. It "provides" the identifiers needed by other object files, and it "requires" other identifiers provided by other files. Linking them together means that the required and the provided objects are connected in an appropriate way so that the program can run.
Example: You have a foo.c which defines the functions foo and test. Then you have a main.c which makes use of these functions and provides a function main. In the end, they are linked together and combined with the startup code which is needed to start a program and which calls main(). The points in main() where foo() and test() are called respectively are marked in a special way so that the linker can put the actual call address there.
Q1. Is this how you actually do it?
No
Since foo.h is already included in foo.c, wouldn't it be sufficient to
include only foo.c in the file in which I want to use its functions?
You should only include .h files; both in the file that defines them, and in the ones that use them. As an extra, that include should be the first one in the file that defines the functions, but in the files that use them, it should go after the rest (standard headers, other packages' headers, ...); the reason for this is to detect errors easily.
Can't I just directly define the functions inside of the foo.c file,
not using the foo.h file at all?
Usually, no. Only static inline functions should do that.
Q2. Do you actually have to put the extern in front of typedefs in
the foo.h file?
No: typedef int foobar_t;
Q3. Let's say that in foo.c I use some standard C libraries like
string.h and math.h . Where should I include them?
In the file that needs them (foo.c). Include in every file only the headers that it needs. No more; no less.
Directly in the foo.c file, in the foo.h file or in both?
foo.c
Are #ifndefinstructions necessary? If so, how do you use them
correctly?
Yes:
// foo.h
#ifndef FOO_H
#define FOO_H
Here go all the contents of foo.h
#endif /* foo.h */
Q4. After writing the foo.c and foo.h file, am I all ready to go?
Like, I don't need to compile them or anything, right? I can
just #include them wherever I need just like that?
You need to compile foo.c into foo.o (object file) and then you probably would like to do a static library (.a) or a dynamic one. You can include it wherever you want, but you will need to prepare your Makefile to do so.
Q5. Somewhere else I've read that if I want to use a custom library
these are the steps that I need to follow:
define the interface (foo.h)
write foo.c #include ing foo.h
creating an object file like this gcc -o foo.o -c foo.c
including foo.h in the program in which I want to use foo.c functions
linking the object file like this gcc my_proj.c foo.o
Are these steps actually necessary?
Yes
Because I haven't seen them mentioned anywhere else. Why do I only
need to include foo.h in the file in which I want to
use foo.c functions?
Read more about compiling and linking.
What exactly is an object file?
A compiled file. Many of them are usually linked together to produce the executable file.
Related
Might be a duplicate but i wasn't able to find a answer for my question.
Usually if you want to import multiple functions from different c files in one main class, one would make a .h file and list up all functions from the .c sources.
My problem is, that all functions are wridden in .asm files. I used extern void asmFunc(int i, char c); to use the function in further code, but they become more and more and i don't want to end up with 200 of those extern lines at the beginning of my main. How can i create a library.h with all assembly functions so i can just write #include "library.h" at the beginning of my main class?
EDIT:
I think i didn't give enough specific information:
I use MINGW gcc and NASM to compile c and asm files
I have to compile all files to .o first so i can match them
The first answer i got didn't work because my compile chain is a bit complicated thanks to the restrictions i have on Windows (i want Linux back)
It looks like this:
I got a folder containing three folders with seperated library-like structures: bwt (basic window toolkit), io and std (stuff like strlen)
They are compiled into bwt.o io.o and std.o.
Now i want to make a .h file for each of them so i can #include "bwt.h" in all kernel classes which need them. How do i get gcc to realize, that all functions in bwt.h are defined in bwt.o?
Since you have a .o file, it doesn't matter that the source for those routines is assembly. As long as you know how to call them as C functions that's what matters.
So put all of your extern declarations for the assembly functions in library.h, then #include "library.h" in your main file. Then you can link them.
gcc -c main.c
gcc -o program main.o asmfunctions.o
You can:
Make a file
Save the file as library.h (same folder as your C file)
Put your extern declarations* in the file
Add #include "library.h" in your C file
#include is literally copy-paste. You can put some code into another file, and then you can #include that file, and the compiler pretends you wrote the code in the main file directly. That's how it works.
* by the way, you don't need to write extern when declaring functions - only variables.
I am working on a program that is using libgit2. I had kept the code in a single c file. Say:
somefile.c
I compile and use it. Now I want to separate some of the details related to libgit2 into a separate library inside the project. So I created an h file with the data structures that I need and the definitions of the functions I want to use. So far, nothing fancy: init stuff, pass in the path to the repo and s a treeish... those are const * constant.... then In the library c file I have an implementation of the functions in the .h file.
Currently, the layout is like this:
include/mylib.c
include/mylib.h
somefile.c
In include/mylib.h I have one struct and a couple of functions:
struct blah {} blah_info;
int blah_init(cont char * path, const char * treeish);
int blah_shutdown();
In include/mylib.c I include mylib.h:
#include "mylib.h" # notice that I don't have to use "include" in the path
And then I have definitions for the 2 functions that I put in the .h file.
In somefile.c now I am including the library c file, not the .h file (and no need to include git2.h anymore either as that is done in mylib files now).
#include "include/mylib.c"
And this allows me to compile and run the program, just like it did before I separated it into pieces but I know it's possible to include include/mylib.h from the original .c file. I think it requires to build the library before then going into compiling the final program? What steps are required for that?
Right now I'm compiling by hand in a shell script calling GCC in a single shot... so if I need to run more commands to do so, just let me know so that I add them to the script.
In somefile.c, you need to do this:
#include "include/mylib.h"
And make sure you define these functions in mylib.c:
int blah_init(cont char * path, const char * treeish) {
}
int blah_shutdown() {
}
And then declare them in mylib.h:
struct blah {} blah_info;
int blah_init(cont char * path, const char * treeish);
int blah_shutdown();
And when you compile, include both somefile.c and mylib.c as input files.
#include directive is used to insert content of a file somewhere else and it's mostly used to include headers so compiler knows what is what (types, constants, etc), then linker puts all compiled files into one single executable.
to make sure header is included only once to a single file you use something called conditional compilation, it's done with preprocessor (before compilation)
yourlib.h
#ifndef YOUR_LIB_H_ //there are many naming conventions but I prefer this one
#define YOUR_LIB_H_
//all your declarations go here
#endif //YOUR_LIB_H_
//you should put in comment what's that condition for after every endif
now in yourlib.c you include that header and then write your definitions
#include "yourlib.h"
//all your definitions go here
and same thing for your main file, just include the header and compiler knows what to do
#include "yourlib.h"
//your code goes here
How do you have a header file for a function and the implementation of that function in different files? Also, how do you have main in yet another file and call this function?
The advantage is so that this function will then be an independent component which can be reused, right?
This is best illustrated by an example.
Say we want a function to find the cube of an integer.
You would have the definition (implementation) in, say, cube.c
int cube( int x ) {
return x * x * x;
}
Then we'll put the function declaration in another file. By convention, this is done in a header file, cube.h in this case.
int cube( int x );
We can now call the function from somewhere else, driver.c for instance, by using the #include directive (which is part of the C preprocessor) .
#include "cube.h"
int main() {
int c = cube( 10 );
...
}
Finally, you'll need to compile each of your source files into an object file, and then link those to obtain an executable.
Using gcc, for instance
$ gcc -c cube.c #this produces a file named 'cube.o'
$ gcc -c driver.c #idem for 'driver.o'
$ gcc -o driver driver.c cube.c #produces your executable, 'driver'
Actually you can implement any function in header files for better performance(when implementing libraries for example) as long are not referenced to a specific object(actually it won't compile that).
By the way even with that way, you have separate interface and implementation ;)
Of course you will have include gurads in you header files to avoid "multiple definition" errors.
In C/C++, non-inline functions should be defined only once. If you put function defination
in header files, you will get "multiple defination" link error when the header file is included more than once.
I know this is common in most languages, and maybe in C, as well. Can C handle separating several functions out to a separate file and having them be included?
The functions will rely on other include files, as well. I want the code to retain all functionality, but the code will be reused in several C scripts, and if I change it once I do not wish to have to go through every script and change it there, too.
Most definitely! What you're describing are header files. You can read more about this process here, but I'll outline the basics below.
You'll have your functions separated into a header file called functions.h, which contains the following:
int return_ten();
Then you can have a functions.c file which contains the definition of the function:
int return_ten()
{
return 10;
}
Then in your main.c file you can include the functions.h in the following way:
#include <stdio.h>
#include "functions.h"
int main(int argc, char *argv[])
{
printf("The number you're thinking of is %d\n", return_ten());
return 0;
}
This is assuming that your functions.h file is in the same directory as your main.c file.
Finally, when you want to compile this into your object file you need to link them together. Assuming you're using a command-line compiler, this just means adding the extra definition file onto the end. For the above code to work, you'd type the follow into your cmd: gcc main.c functions.c which would produce an a.out file that you can run.
Declare the functions in header files and then implement them in .c files. Now you can #include the header files into any program that uses the functions and then link the program against the object files generated from the .c files.
Say you have a file with a function that you want to use elsewhere:
int func2(int x){
/*do some stuff */
return 0;
}
what you would do is split this up into a header file and a source file. In the header file you just have the function declaration, this tells the compiler that that function does exist, even if it is in a different file. The header might be called func2.h might look like this:
#ifndef HEADER_FUNC2_H
#define HEADER_FUNC2_H
int func2(int x);
#endif /*HEADER_FUNC2_H*/
The #ifndef HEADER_FUNC2_H part is to make sure that this only gets used once so that there are no multiple definitions going on.
then in the source func2.c file you have the actual function itself:
int func2(int x){
/*do some stuff */
return 0;
}
and in any other file now that you use func2 you have to include the header. You do this with #include "func2.h". So for example if we wanted to call func2 from randomfile.c it would be like this:
#include "func2.h"
/* rest of randomfile.c */
func2(1);
Then the last step is to link the object file that contains the function with the compiler when you compile.
If you want to reuse functions across multple programs, you should place them in a library and link it with the rest of your code.
If you want to share the same definitions (e.g. macros, types, ...) you can place them in a header file and include them with #include.
Please refrain from directly "#include" function code into a source file, it's a bad practice and can lead to very problematic situations (especially if you are a beginner, as your tag suggests).
Consder that normally when you have a set of functions you want to share and reuse, you will need both! You will usually end up with a myfuncs.lib (or libmyfuncs.a) library and a myfuncs.h header.
In the programs where you want to reuse your existing functions, you will include the header and link against the library.
You can also look at how to use dynamic libraries once you have mastered the usage of static libraries.
I'm a C newbie and I was just trying to write a console application with Code::Blocks. Here's the (simplified) code:
main.c:
#include <stdio.h>
#include <stdlib.h>
#include "test.c" // include not necessary for error in Code::Blocks
int main()
{
//t = test(); // calling of method also not necessary
return 0;
}
test.c:
void test() {}
When I try to build this program, it gives the following errors:
*path*\test.c|1|multiple definition of `_ test'|
obj\Debug\main.o:*path*\test.c|1|first defined here|
There is no way that I'm multiply defining test (although I don't know where the underscore is coming from) and it seems highly unlikely that the definition is somehow included twice. This is all the code there is.
I've ruled out that this error is due to some naming conflict with other functions or files being called test or test.c. Note that the multiple and the first definition are on the same line in the same file.
Does anyone know what is causing this and what I can do about it? Thanks!
You actually compile the source code of test.c twice:
The first time when compiling test.c itself,
The second time when compiling main.c which includes all the test.c source.
What you need in your main.c in order to use the test() function is a simple declaration, not its definition. This is achieved by including a test.h header file which contains something like:
void test(void);
This informs the compiler that such a function with input parameters and return type exists. What this function does ( everything inside { and } ) is left in your test.c file.
In main.c, replace #include "test.c" by #include "test.h".
A last point: with your programs being more complex, you will be faced to situations when header files may be included several times. To prevent this, header sources are sometimes enclosed by specific macro definitions, like:
#ifndef TEST_H_INCLUDED
#define TEST_H_INCLUDED
void test(void);
#endif
The underscore is put there by the compiler and used by the linker. The basic path is:
main.c
test.h ---> [compiler] ---> main.o --+
|
test.c ---> [compiler] ---> test.o --+--> [linker] ---> main.exe
So, your main program should include the header file for the test module which should consist only of declarations, such as the function prototype:
void test(void);
This lets the compiler know that it exists when main.c is being compiled but the actual code is in test.c, then test.o.
It's the linking phase that joins together the two modules.
By including test.c into main.c, you're defining the test() function in main.o. Presumably, you're then linking main.o and test.o, both of which contain the function test().
You shouldn't include other source files (*.c) in .c files. I think you want to have a header (.h) file with the DECLARATION of test function, and have it's DEFINITION in a separate .c file.
The error is caused by multiple definitions of the test function (one in test.c and other in main.c)
I had similar problem and i solved it following way.
Solve as follows:
Function prototype declarations and global variable should be in test.h file and you can not initialize global variable in header file.
Function definition and use of global variable in test.c file
if you initialize global variables in header it will have following error
multiple definition of `_ test'|
obj\Debug\main.o:path\test.c|1|first defined here|
Just declarations of global variables in Header file no initialization should work.
Hope it helps
Cheers
Including the implementation file (test.c) causes it to be prepended to your main.c and complied there and then again separately. So, the function test has two definitions -- one in the object code of main.c and once in that of test.c, which gives you a ODR violation. You need to create a header file containing the declaration of test and include it in main.c:
/* test.h */
#ifndef TEST_H
#define TEST_H
void test(); /* declaration */
#endif /* TEST_H */
If you have added test.c to your Code::Blocks project, the definition will be seen twice - once via the #include and once by the linker. You need to:
remove the #include "test.c"
create a file test.h which contains the declaration:
void test();
include the file test.h in main.c
If you're using Visual Studio you could also do "#pragma once" at the top of the headerfile to achieve the same thing as the "#ifndef ..."-wrapping. Some other compilers probably support it as well ..
.. However, don't do this :D Stick with the #ifndef-wrapping to achieve cross-compiler compatibility. I just wanted to let you know that you could also do #pragma once, since you'll probably meet this statement quite a bit when reading other peoples code.
Good luck with it
Ages after this I found another problem that causes the same error and did not find the answer anywhere. I thought to put it here for reference to other people experiencing the same problem.
I defined a function in a header file and it kept throwing this error. (I know it is not the right way, but I thought I would quickly test it that way.)
The solution was to ONLY put a declaration in the header file and the definition in the cpp file.
The reason is that header files are not compiled, they only provide definitions.