ov7a
ov7a

Reputation: 1594

g++ generates wrong symbols in dynamic library

I'm trying to make simplest so library.

#include <stdio.h>
   void PutLoLoLo(){
   puts("Lololo");
}

compiling with g++:

g++ -shared -fPIC main2.cpp -o simple.so -Wall

and I get this in symbol table:

:$ nm -D --dynamic --defined-only simple.so 
0000048c T _Z9PutLoLoLov
00002010 A __bss_start
00002010 A _edata
00002018 A _end
000004f8 T _fini
00000354 T _init

but I expect something like this:

0000048c T PutLoLoLo
00002010 A __bss_start
00002010 A _edata
00002018 A _end
000004f8 T _fini
00000354 T _init

So, of course, I get dlopen() error when I try to load it.

Please, help me: what am I doing wrong?

Upvotes: 3

Views: 306

Answers (2)

Dave Rager
Dave Rager

Reputation: 8150

That looks like C++ name mangling. Try this:

extern "C" void PutLoLoLo(){
   puts("Lololo");
}

Upvotes: 3

acm
acm

Reputation: 12727

C++ mangles symbol names. If you want to avoid the mangling, the function must be declared as extern C, like so:

#include <stdio.h>
   extern "C" void PutLoLoLo(){
   puts("Lololo");
}

Then the link:

$ g++ -shared -fPIC lolo.cc -o lolo.so -Wall

Will give you what you expect:

$ nm -D --dynamic --defined-only ./lolo.so 
000000000000061c T PutLoLoLo
0000000000002018 A __bss_start
0000000000002018 A _edata
0000000000002028 A _end
0000000000000668 T _fini
0000000000000500 T _init

You will be able to dlopen the library and obtain the symbol via its 'normal' name. The function is restricted to having C semantics. So you can't, for instance, do this with member functions, or use objects with class semantics as arguments, etc. So if you need to pass in objects, you will need to take those arguments as void *, and cast.

Upvotes: 4

Related Questions