问题
I am getting undefined symbol
error while loading library dynamically.
Here is my code snippet that generates this error :
int main ()
{
void *lib_handle = NULL;
MyClass* (*create)();
void (*destroy)(MyClass*);
char *error;
lib_handle = dlopen ("./libshared.so", RTLD_LAZY);
if (lib_handle == NULL)
{
fprintf(stderr, "%s\n", dlerror());
exit(1);
}
create = (MyClass* (*)()) dlsym(lib_handle, "create_object");
if ((error = dlerror()) != NULL)
{
fprintf(stderr, "%s\n", error);
exit(1);
}
destroy = (void (*)(MyClass*)) dlsym(lib_handle, "destroy_object");
MyClass *myClass = (MyClass*) create;
destroy(myClass);
dlclose(lib_handle);
}
But when I load library simply by commenting above code and exporting library path everything works like charm.
For dynamic linking I am using the following command on command prompt.
g++ -Wl,--export-dynamic shared_user.cpp -ldl
Any help would be appreciated.
回答1:
You're very likely seeing Name Mangling in action here.
If you want to use dlopen()
/ dlsym()
with C++ shared libraries, you either need to:
- declare the functions you want to lookup through
dlsym()
asextern "C" { ... }
so that the C++ compiler creates unmangled names for them.
This is only possible if the function you try to access is a non-member or static member function, and not overloaded (only a single signature); C++ can't create unmangled names in other situations.
If one requested the compiler to do so viaextern "C" { ... }
and it's possible to create an unmangled name, it ends up verbatim in the ELF symbol table. You can then look it up usingdlsym()
exactly like you would for any C function. - Find out what the mangled name of the function is, and use that in your
dlsym()
call.
The latter you can do via the nm
utility. For example:
$ nm libstdc++.a | grep -v '^ ' | grep unexpected
0000000000000000 T __cxa_call_unexpected
0000000000000000 T _ZN10__cxxabiv112__unexpectedEPFvvE
0000000000000000 T _ZSt10unexpectedv
0000000000000000 T _ZSt14set_unexpectedPFvvE
0000000000000000 D _ZN10__cxxabiv120__unexpected_handlerE
These are the mangled names, what the C++ compiler has actually put into the ELF object. If you use the -C
option to request nm
to demangle the names for you, you get:
$ nm -C libstdc++.a | grep -v '^ ' | grep unexpected
0000000000000000 T __cxa_call_unexpected
0000000000000000 T __cxxabiv1::__unexpected(void (*)())
0000000000000000 T std::unexpected()
0000000000000000 T std::set_unexpected(void (*)())
0000000000000000 D __cxxabiv1::__unexpected_handler
That means for this lib, if you'd want to get the function pointer to std::unexpected()
from it, you'd have to request dlsym(hdl, "_ZN10__cxxabiv112__unexpectedEPFvvE");
to make the lookup succeed.
来源:https://stackoverflow.com/questions/9837009/getting-undefined-symbol-error-while-dynamic-loading-of-shared-library