Reputation: 1594
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
Reputation: 8150
That looks like C++ name mangling. Try this:
extern "C" void PutLoLoLo(){
puts("Lololo");
}
Upvotes: 3
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