Here is the sample code of shared library:
#include <stdio.h>
extern void test();
__attribute__((used, constructor)) static void so_init()
{
printf("loaded\n");
test();
}
and here is the main:
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
__attribute__((used)) void test()
{
printf("test\n");
}
int main(int argc, char** argv)
{
printf("hello world\n");
return 0;
}
and the makefile:
so:a.c
$(CC) -fPIC -c a.c -o a.o
$(CC) a.o -fPIC -shared -o liba.so
test:m.c
$(CC) -fPIC -c m.c -o m.o
$(CC) m.o -fPIC -o test -L./ -la -Wl,-rpath,./
It works as I expect:
loaded
test
hello world
BUT, when I use dlopen to load that so, something goes wrong. Now, main is:
__attribute__((used)) void test()
{
printf("test\n");
}
int main(int argc, char** argv)
{
printf("hello world\n");
void* so = dlopen("./liba.so", RTLD_LAZY);
printf("%p\n", so);
dlclose(so);
return 0;
}
and Makefile is:
so:a.c
$(CC) -fPIC -c a.c -o a.o
$(CC) a.o -fPIC -shared -o liba.so
test:m.c
$(CC) -fPIC -c m.c -o m.o
$(CC) m.o -fPIC -o test -ldl
and the result of running is:
hello world
loaded
./test: symbol lookup error: ./liba.so: undefined symbol: test
It seems dlopen calls function so_init, but function so_init can not find symbol: test which is at main.
So, focus on constructor, what's the difference between linked at compile time and load at run time? Why dlopen can not find symbol? How can I fix it?
Thanks.