I have some global variable defined in global.c file as below:
int globalvar;
I have a header file global.h that declares this variable as extern
extern int globalVar;
Now I have main.c that gets linked with compiled global.o (compiled from global.c) having code to open (using dlopen) a shared object sh.so that gets built from sh.c with access to globalVar, through global.h. Although, my executable has definition of globalVar (statically linked), when I load the dynamically linked library sh.so, it says undefined globalVar. How to handle this?
Although, my executable has definition of globalVar (statically linked), when I load the dynamically linked library sh.so, it says undefined globalVar.
This is expected. An ELF binary has two symbol tables: a regular one and one used for dynamic linking. You can examine them like so:
nm a.out | grep globalVar # expected: address D globalVar
nm -D a.out | grep globalVar # expected: no output
The reason linker doesn't put globalVar
into the dynamic symbol table is that (at link time) nothing outside of the binary needs that symbol.
How to handle this?
There are a few ways.
-rdynamic
to your link line, you'll be asking the linker to export every defined symbol into the dynamic symbol table. While in general this is a a bad idea, it's the fastest way to solve your problem here.-Wl,--export-dynamic-symbol=globalVar
to export just the globalVar
-Wl,--dynamic-list=globals.txt
and put globalVar
into the globals.txt
file.-Wl,--dynamic-list-data
to export all global data variables (this is only slightly better than -rdynamic
).