Reputation: 744
I have seen a GCC link with a C++ shared library, but I am not able to reproduce it on my own. So first I create a C++ library with a testfunction:
g++ -shared -o libtest.so test.c
Then I have a test main function which calls the library function and compile it like this
gcc -o prog.out main.c -L. -ltest
Then i receive the error
undefined reference to 'testfunc'
which i think is caused by different refernce in the library ... C names the function testfunc and C++ names the function [some stuff]__testfunc[maybe again some stuff].
I have also tried to use
gcc -o prog.out main.c -l:libtest.so
but this results in the same error.
Therefore, my question is: How is it possible to link a c++ library with gcc to a c file?
Update: I know i can use extern "C"
, but that's not the way it is solved. Maybe there are some parameters for the linker instead?
Update2: Just thought it could also be possible that the first part is just compiled with c++ and linked with gcc. Also tried this:
g++ -c testlib.c -o testlib.o
gcc -shared -o libtest.so testlib.o
gcc -o prog.out -l:libtest.so
still doesn't work. Is there something wrong with the flags?
Upvotes: 5
Views: 12708
Reputation: 264729
When you use g++ it compiles ALL source as C++. This means all function use the C++ ABI (this also including name mangling). When you use gcc it compiles *.c files using the C ABI (no name mangling).
Thus the same function compiles with the two different compilers will generate different functions (in a lot of ways). That's because they are different languages.
To force g++ to compile a function using the C ABI prefix it with extern "C"
extern "C" void testfunc(char*);
Alternatively use the block version
extern "C" {
<multiple Functions>
}
To be honest I never compile anything with gcc anymore (unless there is some hard requirement to do so (in which case I usually fix the code so it works in C++)). If you compile all files with g++ just makes the processes simpler.
Upvotes: 2
Reputation:
If you are sure it's not because of name mangling. Then it means gcc could not find the library try giving the full path of the library unless the .so
file is in standard location. If you are not sure then recheck for any conflict in variable (function) name. Use namespaces to group classes and define the functions inside the classes to avoid naming conflict
Upvotes: 0
Reputation: 213837
Yes, the problem has nothing to do with shared libraries (I think...) and everything to do with name mangling.
In your header, you must declare the function like this:
#ifdef __cplusplus
extern "C" {
#endif
void testfunc(void);
#ifdef __cplusplus
}
#endif
This will cause testfunc
to have the same symbol and calling conventions for both C and C++.
On the system I'm using right now, the C symbol name will be _testfunc
and the C++ symbol name (assuming you don't use extern "C"
) will be __Z8testfuncv
, which encodes information about the parameter types so overloading will work correctly. For example, void testfunc(int x)
becomes __Z8testfunci
, which doesn't collide with __Z8testfuncv
.
Upvotes: 8