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.
Related
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
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.
Well,I am making a program that can Implement every form of Data structure i.e,linked list,queue,stack. And created separate file for each ,Now I want to use each of the separate file in a single driver program.
I've linked the file as:
#include"filename.c"
But an error shows up no such file or directory. And yeah, any other thing which i need to implement to use the functions of included files in the driver program .
You don't include .c files, rather .h files.
Assuming you have folder containing your main.c file and a datastructs.c file, create a datastructs.h file that contains all the function declarations.
datastructs.c
#include <stdio.h>
#include "datastructs.h"
void hello() {
printf("hello, world!\n");
}
datastructs.h
void hello();
Now, in the main.c - the C file containing the main function - include the datastructs.h file and invoke all the functions you want:
#include "datastructs.h"
void main() {
hello();
}
Make sure to compile every source you're using, it'll make sure to link everything correctly:
gcc datastructs.c main.c -o main
This is a very basic approach, there are more out there - which probably are even better than this - but it will get the job done.
Make sure to check out how Makefile and make works, this way you can deal with this kind of tasks better.
I want to include a .c file in another. Is it possible right? It works well if I include a header file in a .c file, but doesn't work as well if I include a .c file in another .c file.
I am using Visual Studio and I get the following error:
main.obj : error LNK2005: _sayHello already defined in sayHello.obj
/* main.c */
#include "sayHello.c"
int main()
{
return 0;
}
/* sayHello.c */
#include <stdio.h>
void sayHello()
{
printf("Hello World");
}
I don't know what this error could mean. Time to ask more advanced C coders. :)
I want to include a .c file in another.
No you don't. You really, really don't. Don't take any steps down this path; it only ends in pain and misery. This is bad practice even for trivial programs such as your example, much less for programs of any real complexity. A trivial, one-line change in one file will require you to rebuild both that file and anything that includes it, which is a waste of time. You lose the ability to control access to data and functions; everything in the included .c file is visible to the including file, even functions and file scope variables declared static. If you wind up including a .c file that includes another .c file that includes another .c file und so weiter, you could possibly wind up with a translation unit too large for the compiler to handle.
Separate compilation and linking is an unequivocal Good Thing. The only files you should include in your .c files are header files that describe an interface (type definitions, function prototype declarations, macro defintions, external declarations), not an implementation.
It works, but you need to be careful with how you build the program. Also, as folks have pointed out in comments, it's generally considered a bad idea. It's unexpected, and it creates problems like these. There are few benetfits, especially for what seems like a trivial program. You should probably re-think this approach, altogether.
After doing something like this, you should only compile main.c, and not attempt to link it with the result of compiling sayHello.c, which you seem to be doing.
You might need to tell Visual Studio to exclude the latter file from the build.
Yes, any '.c' file can be included into another program.
As one include '.h' file like 'stdio.h' in the program.
After that we can call those function written into this external file.
test.c::
#include<stdio.h>
#include<conio.h>
void xprint()
{
printf("Hello World!");
}
main.c::
#include "test.c"
void main()
{
xprint();
getch();
}
Output:: Hello World!
This is a linker error. After compiling all your .c files to .obj files (done by the compiler) the linker "merges" them together to make your dll/exe. The linker has found that two objects declare the same function (which is obviously not allowed). In this case you would want the linker to only process main.obj and not sayhello.obj as well (as its code is already included in main.obj).
This is because in main.obj you will ALSO have the sayHello() function due to the include!
sayHello.h
#include <stdio.h>
void sayHello(void);
main.c
#include "sayHello.h"
int main()
{
sayHello();
return 0;
}
You probably defined two times this function
void sayHello()
{
printf("Hello World");
}
one in your current file and one in sayhello.c
You must remove one definition.
The problem seems to be that sayHello.c got compiled into an object file called sayHello.obj, and main.c (also including all the source text from sayHello.c), got compiled into main.obj, and so both .obj files got a copy of all the external symbols (like non-static function definitions) from sayHello.c.
Then all the object files were supposed to get "linked" together to produce the final executable program file, but the linking breaks when any external symbols appear more than once.
If you find yourself in this situation, you need to stop linking sayHello.obj to main.obj (and then you might not want to compile sayHello.c by itself into its own object file at all).
If you manually control every step of the build (like you might when using the CLI of your compiler), this is often just a matter of excluding that object file from the invocation of the linker or compiler.
Since you are using Visual Studio, it's probably making a bunch of assumptions for you, like "every .c file should be compiled into its own object file, and all those object files should be linked together", and you have to find a way to circumvent or disable this assumption for sayHello.c.
One easy and somewhat idiomatic solution might be to rename sayHello.c into sayHello.c.inc.
//THIS IS THE MAIN FILE//
#include "test.c"
int main()
{
multi(10);
}
//THIS IS THE TEST FILE//
#include<stdio.h>
void multi(int a)
{
printf("%d",a*2);
}
POINTS TO BE NOTED:
Here you need to run the program which contains "main()" function.
You can avoid the "stdio.h" header file in main function. Because, you are including the file which already contains the "stdio.h" header file.
You have to call the function from the "main" file.
The including file should be "file_name.c" not "file_name.h". Because usually we use .h extension for the header file. Since we are including another program file and not the header file, we have to use .c. Otherwise it will give you Fatal Error and the Compilation gets terminated.
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.