-
Dynamic loading with C++
I have problem with dynamic loading function with C++ (in C it works).
Let test.cpp be
Code:
#include <iostream>
#include <string>
using namespace std;
void f(string s)
{
cout << s << endl;
}
and main.cpp
Code:
#include <dlfcn.h>
#include <string>
using namespace std;
extern "C" void f(string);
int main()
{
void* handle = dlopen("libtest.so", RTLD_LAZY);
void (*test)(string) = dlsym(handle, "f");
(*test)("Hello, World!");
dlclose(handle);
}
Then, I made libtest.so with
Code:
g++ -c test.c
g++ -shared -fPIC -o libtest.so test.o
put it into /usr/lib and set appropriate file attributes. But,
gives error main.cpp:12: error: invalid conversion from `void*' to `void (*)(std::string)'.
Why? Same thing works in C with char* and printf() instead of string and cout.
-
have you tried to cast the pointer returned by the dlsym function to the proper type of the pointer?
-
If I cast it with
Code:
void (*test)(string) = (void (*)(string))dlsym(handle, "f");
then it compiles but on run gives Segmentation fault.
-
Trouble is the namemangling.
have a look in the library how the function is actually called. ( use nm ).
Guess there should be a better way.
Got this to run:
the lib
Code:
#include <iostream>
#include <string>
using namespace std;
void testfunc(string s)
{
cout << s << endl;
}
Code:
#include <dlfcn.h>
#include <string>
#include <iostream>
using namespace std;
typedef void (*test)(string);
int main()
{
void* handle = dlopen("libtest.so", RTLD_LAZY);
if ( 0 == handle ) {
cout << "failed to load 'libtest.so'." << endl;
exit(1);
}
test t = (test)dlsym(handle, "_Z8testfuncSs");
if ( 0 == t ) {
cout << "failed to load 'testfunc()'." << endl;
exit(1);
}
t("Hello, World!");
dlclose(handle);
}
Kurt
-
After some experimenting I think the easiest way is to declare the exported function in the dynamic libarary as extern "C", and use it as extern "C" as well. This way there are no namemangling issues.
Kurt
-
There is still one other issue: dlsym() returns a void*, and conversions between object- and function-pointers are absolutely invalid in C++. (GCC allows them, but it will issue a warning on most levels.)
See here:
http://www.trilithium.com/johan/2004...em-with-dlsym/
-
To prevent SegFault - just check the returned pointer before use
-
extern declaration must be placed into f's definition in the test.cpp and removed from main.cpp.
Thanks for the help, especially for the URL about pointer conversions.