我想创建一个共享库,可以通过两种不同的方式加载到目标中:
dlsym
我的共享库如下所示:
#include "stdio.h"
void __attribute__ ((constructor)) my_load(void);
void my_load(void) {
printf("asdf");
}
void someFunc(void) {
printf("someFunc called");
}
我正在编译它:
all:
gcc -fPIC -g -c -Wall MyLib.c
gcc -shared -W1,-soname,MyLib.so.1 -o MyLib.so.1.0.1 -lc
我不希望用ldconfig
等安装它。目标进程如下所示:
#include <stdio.h>
#include <dlfcn.h>
void func1() {
printf("%d\n", 1);
}
void func2() {
printf("%d\n", 2);
}
void func3() {
printf("%d\n", 3);
}
int main() {
void* lib_handle = dlopen("/home/mike/Desktop/TargetProcess/MyLib.so.1.0.1",
RTLD_NOW|RTLD_GLOBAL);
if(lib_handle == NULL) {
printf("Failed loading lib\n");
} else {
printf("Loaded lib successfully\n");
void (*some_func)() = dlsym(lib_handle, "someFunc");
printf("%p\n", some_func);
dlclose(lib_handle);
}
func1();
func2();
func3();
return 0;
}
目标编译如下:
all:
gcc TestProg.c -ldl -o TestProg
我的问题是:
dlopen
进行动态加载,为什么my_load
似乎没有被调用?dlsym
总是返回nil
,即使dlopen
返回非空?同样,nm
也不会将my_load
或someFunc
列为.so的符号。LD_PRELOAD
加载库?我尝试将.so复制到与目标相同的目录中,然后调用LD_PRELOAD="./MyLib.so.1.0.1" ./TestProg
但是再次my_load
似乎没有被调用。答案 0 :(得分:6)
您的目标文件未链接到您的库中:
gcc -shared -W1,-soname,MyLib.so.1 -o MyLib.so.1.0.1 -lc
将其更改为包含您的目标文件MyLib.o:
gcc MyLib.o -shared -W1,-soname,MyLib.so.1 -o MyLib.so.1.0.1 -lc
更新:只在本地尝试你的命令(没有任何MyLib.c或MyLib.o):
$ gcc -shared -W1,-soname,MyLib.so.1 -o MyLib.so.1.0.1 -lc && echo ok
ok
$ nm MyLib.so.1.0.1
xxxxxxxx a _DYNAMIC
xxxxxxxx a _GLOBAL_OFFSET_TABLE_
w _Jv_RegisterClasses
xxxxxxxx A __bss_start
w __cxa_finalize@@xxxxxxxxxxx
xxxxxxxx d __dso_handle
w __gmon_start__
xxxxxxxx t __i686.get_pc_thunk.bx
xxxxxxxx A _edata
xxxxxxxx A _end
xxxxxxxx T _fini
xxxxxxxx T _init
这是一个空动态库。