Reputation: 4907
I'm experimenting with making a kind of plugin architecture for a program I wrote, and at my first attempt I'm having a problem. Is it possible to access symbols from the main executable from within the shared object? I thought the following would be fine:
testlib.cpp:
void foo();
void bar() __attribute__((constructor));
void bar(){ foo(); }
testexe.cpp:
#include <iostream>
#include <dlfcn.h>
using namespace std;
void foo()
{
cout << "dynamic library loaded" << endl;
}
int main()
{
cout << "attempting to load" << endl;
void* ret = dlopen("./testlib.so", RTLD_LAZY);
if(ret == NULL)
cout << "fail: " << dlerror() << endl;
else
cout << "success" << endl;
return 0;
}
Compiled with:
g++ -fPIC -o testexe testexe.cpp -ldl
g++ --shared -fPIC -o testlib.so testlib.cpp
Output:
attempting to load
fail: ./testlib.so: undefined symbol: _Z3foov
So obviously, it's not fine. So I guess I have two questions: 1) Is there a way to make the shared object find symbols in the executable it's loaded from 2) If not, how do programs that use plugins typically work that they manage to get code in arbitrary shared objects to run inside their programs?
Upvotes: 14
Views: 4609
Reputation: 7506
From The Linux Programming Interface:
42.1.6 Accessing Symbols in the Main Program
Suppose that we use
dlopen()
to dynamically load a shared library, usedlsym()
to obtain the address of a functionx()
from that library, and then callx()
. Ifx()
in turn calls a functiony()
, theny()
would normally be sought in one of the shared libraries loaded by the program. Sometimes, it is desirable instead to havex()
invoke an implementation ofy()
in the main program. (This is similar to a callback mechanism.) In order to do this, we must make the (global-scope) symbols in the main program available to the dynamic linker, by linking the program using the––export–dynamic
linker option:
$ gcc -Wl,--export-dynamic main.c
(plus further options and arguments)Equivalently, we can write the following:
$ gcc -export-dynamic main.c
Using either of these options allows a dynamically loaded library to access global symbols in the main program.
The
gcc –rdynamic
option and thegcc –Wl,–E
option are further synonyms for–Wl,––export–dynamic
.
Upvotes: 1
Reputation: 223023
Try:
g++ -fPIC -rdynamic -o testexe testexe.cpp -ldl
Without the -rdynamic
(or something equivalent, like -Wl,--export-dynamic
), symbols from the application itself will not be available for dynamic linking.
Upvotes: 20