问题
I have a shared library which I want to access symbols from the main program. For example:
main.c
#include <stdio.h>
void bar(void) { puts("bar"); }
extern void foo(void);
int main(void) {
foo();
return 0;
}
foo.c
#include <stdio.h>
extern void bar(void);
void foo(void) {
puts("foo");
bar();
}
I compile and run like:
gcc -c -fpic foo.c
gcc -shared -o libfoo.so foo.o
gcc -L$(pwd) -o test main.c -lfoo
./test
And I get the output I expect:
foo
bar
However, I must use dlopen()
and dlsym()
because I want to have control over when the library is loaded. The changed files are:
main.c
#include <stdio.h>
#include <dlfcn.h>
void bar(void) { puts("bar"); }
int main(void) {
void *handle = dlopen("./libfoo.so", RTLD_LAZY);
void (*foo)(void) = (void(*)(void))dlsym(handle,"foo");
foo();
return 0;
}
foo.c
#include <stdio.h>
#include <dlfcn.h>
extern void bar(void);
void foo(void) {
puts("foo");
bar();
}
I instead compile and run with:
gcc -c -fpic foo.c
gcc -shared -o libfoo.so foo.o
gcc -o test main.c -ldl
./test
However, this time I get the output
foo
./test: symbol lookup error: ./libfoo.so: undefined symbol: bar
How can I reference symbols in the main program from libfoo?
回答1:
You have to add the -rdynamic
option when linking test
:
gcc -o test main.c -ldl -rdynamic
From here:
-rdynamic Pass the flag -export-dynamic to the ELF linker, on targets that support it. This instructs the linker to add all symbols, not only used ones, to the dynamic symbol table. This option is needed for some uses of dlopen or to allow obtaining backtraces from within a program.
来源:https://stackoverflow.com/questions/58174403/symbols-in-the-executable-are-not-preferred-to-symbols-in-the-library