marty bu
marty bu

Reputation: 744

How to link a C++ shared library with gcc

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

Answers (3)

Loki Astari
Loki Astari

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

user1020710
user1020710

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

Dietrich Epp
Dietrich Epp

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

Related Questions