4

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?

marty bourque
  • 734
  • 4
  • 7
  • 20
  • 1
    duplicate http://stackoverflow.com/questions/1068129/c-library-not-linking-using-gcc-g – cyber_raj Jun 25 '12 at 06:45
  • 2
    What do you mean "that's not the way it is solved"? I'm telling you, that **is** the way it is solved, unless there's something you're not telling us. – Dietrich Epp Jun 25 '12 at 06:47
  • @Dietrich Epp Looks like it's done like i wrote in Update2. And I am sure its not done with 'extern' - if you want to have a look at the project: [openjdk](http://openjdk.java.net/) – marty bourque Jun 25 '12 at 06:54

3 Answers3

8

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.

Dietrich Epp
  • 205,541
  • 37
  • 345
  • 415
2

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.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Martin York
  • 257,169
  • 86
  • 333
  • 562
0

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