• Uncategorized

About c : Referencing-global-symbols-from-shared-library-loaded-with-dlopen

Question Detail

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?

Question Answer

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.

You may also like...

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.