Referencing global symbols from shared library loaded with dlopen

余生长醉 提交于 2019-12-13 04:35:51

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!