extern linking problems in Microsoft Visual Studio - c

I have two libs that share a extern variable.
In libA I have the variable declared in the header as such:
extern int Gbl;
then I define it again in the source as:
int Gbl;
next then I set Gbl=1;
in libB, I include libA's header file. And printf Gbl, expecting to get 1 here.
though unfortunately i can't even compile this since I get the error:
undefined symbol '_Gbl' referenced in ....
I was told that this is a linking error, but I'm not sure what to do from here

You need to compile the libB with libA included. This is done by adding -llibA to the compile line. If you don't have library options set correctly, you need to add -lpath_to_library

Related

How to solve "Undefined reference to function" in Eclipse CDT?

I did setup a C project with Eclipse Photon (4.8.0) for developing a program for the ESP-32. I did configure the IDE according to this official setup instructions.
Flashing the ESP-32 works fine. But as soon as I try to include header files from a sub folder, I run into troubles. I have set up a very simple project to illustrate the issue. The project consists of main.c, base/test.h and base/test.c, whereas the test.h and test.c files only contain one function with the signature void function1(void);.
When I try to call function1() in main.c, I get this error in main.c:
Undefined reference to function1()
Please compare to the attached screenshot, where everything is depicted.
How to solve this issue?
This is not a compiler, but rather a linker error.
Note, with #includeing a header file, you only make the external function known to the compiler. You also need to link to the external function during the linking stage. Make sure you include the compiled object file that contains function1 into the link.
Seems like you need to do proper linking.
If you are linking with a library, you need to specify:
The name of the library: Project\Settings\C C++ General\Paths and Symbols\Libraries
Location where the linker should search for this library:
Project\Settings\C C++ General\Paths and Symbols\Library Paths
Important: see Note.
If you are linking with object files, add those to:
Project\Settings\C C++ Build\Settings\Linker\Miscellaneous\Other objects
Note:
If your library name is, for example, libsomething.a, than you need to specify only something as the name; so omit lib prefix and .a suffix.
If your library is not prefixed with lib, then you need to add its name prefixed with :. For example, something.a should be added as :something.a.

Which import directive will import a symbol from a DLL and not add a prefix? (Visual Studio)

The short question is: Which directive adds no prefix to an imported symbol?
I have a library that is 100% C (no C++ and not C compiled with a C++ compiler) It's C top to bottom. (I have to mention that because sometimes folks confuse how Visual Studio works when compiling C using the C++ compiler with C using a C compiler.)
The library was compiled with CMAKE and it outputted a DLL with a symbol table that looks like this:
dumpbin.exe /exports mydll.dll
...stuff...
1 0 00001087 mylib_get_x
..etc..
There's a static lib file too.
dumpbin.exe /exports mydll.lib
...stuff...
mylib_get_x
Notice how there are no weird prefixes? (i.e. no imp on the symbols) This makes the DLL extremely useful when trying to import the functions into things like the FFI in LuaJIT and other compilers/environments.
And I have an app that uses "mylib_get_x()"
/* myfile.c */
... stuff ...
int x;
x = mylib_get_x();
The result is: unresolved external symbol _mylib_get_x referenced in function ...
If I prefix the mylib_get_x() with any of these:
__declspec(dllimport)
__cdecl
__stdcall
_cdecl
extern
extern "C" __declspec(dllimport)
<nothing>
It doesn't matter. It won't work. They add prefixes. Which one adds nothing?
When it was compiled, it had __declspec(dllexport) on it, but it's a 3rd party library, so somehow they got it to avoid the extra prefixes.
I can link in the supplied .lib file that was generated. Same result. (see the dumpbin above that shows the symbol table from the .lib file without prefixes) I can create a manual .def file, generate a lib file from it and link to that. Same result.
I would love it if someone could explain what prefixes go with what directive.
Which directive adds no prefix to the symbol?

how I call a function in my source file including only header file in c?

I would like to know , if I have source file like this
#include <stdio.h>
int main()
{
printf("Hello world");
}
as I know header files contains only prototypes of functions. If it so how can my source file get the function printf ? If I don't include the source file where it has been declared?
thank you
The question is not clear, but there are 2 things which happen before a program gets created,
Compiling (requires prototypes / declarations)
Linking (requires definitions).
Header information is needed for knowing prototypes. Even this would compile fine:
int printf ( const char * format, ... );
int main()
{
printf("Hello world");
}
On linking there will be no issues because the printf function is found in the C standard library, so on linking it will look into the standard directories (of the compiler where the library is kept - bin/lib folder) and link the function.
The source only needs to know the prototype. The problem a programmer will have in this case:
int my_printf ( const char * format, ... );
int main()
{
my_printf("Hello world");
}
The above will compile, but when linking my_printf your code will not have a definition so it will give an error on linking.
Header file has the definitions declarations of the functions ( stdio.h has definition declaration for printf ). The actual function exists in the libraries and gets linked when you compile the code.
When it comes to using libraries, you include the header of the library in your code and you instruct the linker to link using the code files of that library(usually object files). For the standard libraries, the IDE usually instructs the linker to link to them by default.
Assuming you're using gcc as a compiler the standard libraries are linked by default and that is where the function definitions lie. If you'd like to see exactly which libraries are being linked you can pass gcc the -v option which will cause it to dump information about the default options it will use including the library paths and default libraries and object files that will be linked in.
If you give the -Wl,--verbose option, gcc will pass the --verbose to the linker which will dump exactly where it's looking for libraries, including both failed and successful searches
gcc -v foo.c -Wl,--verbose
The header file stdio.h would declare printf as an extern function, i.e., it is defined elsewhere. The compiler is happy as long as functions you use have a declaration. The linker is the one that resolves these dependencies.
A very useful thing to do when you start asking good questions like this is to play with some linker commands.
Assuming you're on *nix, once you have your executable file (lets call it foo), do:
ldd foo
You should see a list of libraries that were linked with while creating foo.
libc.so should be one among those. It contains the definition for printf among other things!
You can refer to this link to learn more

Why do I get 'multiple definition' errors when linking against an archive?

I'm using CppUTest to test the C code defined in a fornol.c source file. That file defines the main production main() function.
I also have an AllTests.cpp file that also has a main() function, but that main() is supposed to be used only when running the unit tests.
AllTests.cpp gets compiled to a .o file, whereas fornol.c gets compiled to a libfornol.a archive.
Then CppUTest tries to link everything together, but here is what I get instead:
Linking fornol_tests
cc -o fornol_tests objs/tests/AllTests.o objs/tests/FornolTests.o lib/libfornol.a ../../CppUTest/lib/libCppUTest.a ../../CppUTest/lib/libCppUTestExt.a -lstdc++ -lgcov
lib/libfornol.a(fornol.o): In function `main':
/home/dlindelof/Work/endor/nol/fornol/fornol.c:453: multiple definition of `main'
objs/tests/AllTests.o:/home/dlindelof/Work/endor/nol/fornol/tests/AllTests.cpp:4: first defined here
collect2: ld returned 1 exit status
It looks as if the main() function defined in fornol.c and present in the archive libfornol.a conflicts with the main() defined in AllTests.cpp. But my understanding was that archive/library files are searched only if/when a given symbol hasn't been referenced yet. It should therefore not be a problem to have the same symbol defined more than once, provided all definitions are in archive/library files.
What am I doing wrong here?
You need to remove the main() from AllTests.cpp and put it in its own source file.
When a linker links in a library, it can't split object files in the library; it has to either link or omit each object file in the library as a unit. (I know LLVM is different, but that's another topic.) This is why, if you look at the source for a library like glibc, each function gets its own source file.
So what's happening to you is that the linker needs to pull in an object file (fornol.o) from the library (libfornol.a) to satisfy dependencies, but that object file carries a duplicate symbol with it (main).
It's perfectly okay to put test code in a library (we do this routinely where I work), but keep it in its own source files (we traditionally use main.cc). (This is a better test anyway, because test code should not have access to static-declared symbols.)
A library is supposed not to have a main() function as it is a library.
You should remove that main() from fornol.c and compile it again.
main() is the entry point of an executable file's source code, since a library (especially a static ".a" library) is only pre-compiled source code, you cannot use a main in there.
If you want a main production entry point of your library you could rename the main() in fornol.c to something more explicit and less reserved such as "fornolMain()" for example.
A static library is compiled in your binary executable and thus is not searched only if the symbol is loaded. It is exactly the same as compiling fornol.c and linking fornol.o and your other .o

Undefined reference in C with gcrypt.h

I'm trying to use the library gcrypt.h but show this error:
undefined reference to `gcry_md_get_algo_dlen'
The code is:
int algo = GCRY_MD_SHA1;
unsigned int hash_len = gcry_md_get_algo_dlen(algo);
unsigned char hash[hash_len];
How can I fix it?
Make sure you have the most recent version of the library http://www.gnupg.org/download/#libgcrypt
If you have the right version make sure you added the library itself to your linker settings in Eclipse.
To do so:
Right-Click on your project -> Properties / C/C++Build / Settings / GCC C++ Linker / Libraries
There you add to libraries "gcrypt" ( you don't at the "lib" to it )
And also make sure that ( if the lib isnt under a system path ) you add the path where the library itself lies.
It looks like you are facing a Linking Error (Undefined reference to a function)
You have included the header "gcrypt.h" but the object file is not linked to your main file.
Library is NOT the same as the header (.h) file. C libraries are collections of compiled objects which are LINKED to your object code by the linker. Header files are lexically included by the preprocessor.
When you compile, you need to make sure that the libraries are where they're supposed to be AND the header files are where they're supposed to be. Either one can mess you up. Make sure that .o files are linked properly

Resources