Mac OS X为动态加载提供了一个有用的库,名为dyld。在动态加载处理的许多有趣函数中,有一个函数允许安装回调,每当加载或卸载图像时,由dlopen
和dlclose
分别调用dyld。这些功能分别为void _dyld_register_func_for_add_image(void (*func)(const struct mach_header* mh, intptr_t vmaddr_slide))
和void _dyld_register_func_for_remove_image(void (*func)(const struct mach_header* mh, intptr_t vmaddr_slide))
。
我知道Linux不可能有一个确切的端口,因为dyld函数处理mach-o文件而Linux使用ELF文件。
那么,是否有相当于Linux的dyld库。或者,至少在任何Linux库中是否存在这两个函数_dyld_register_func_for_add_image
和_dyld_register_func_for_remove_image
的等价物?或者我必须自己实现我自己的这两个版本,这不是那么难,但我必须找到一种方法,使dlopen
和dlclose
调用回调函数,只要它们被调用。
修改
为了使事情更清楚,我需要创建一个具有回调函数的库,只要dlopen
动态加载外部库,就必须调用该函数。我的回调函数必须对任何动态加载的库执行一些操作。
答案 0 :(得分:1)
是的,使用-ldl
标准库
更确切地说:
-fPIC
标志编译插件的源代码,以获取与位置无关的代码对象文件*.pic.o
gcc -shared
您的*.pic.o
文件制作共享库插件(您还可以链接其他共享库)。constructor
和destructor
函数(或带有显式构造函数和析构函数的静态C ++数据,因此得名)。在__attribute__((constructor))
插件的dlopen
期间调用__attribute__((destructor))
的函数,在dlclose
时间内调用插件中-rdynamic
的函数extern "C"
属性相关联非常有用&只要插件调用主程序中的某些函数,就需要。dlsym
您的C ++插件函数(程序所需)dlopen
来获取插件中的函数或数据地址。 _dyld_register_func_for_add_image
确实没有类似dlopen
的钩子。您可能希望使用构造函数和/或dl_iterate_phdr(3)来模仿它。
如果你可以更改插件(你module_start
的共享对象),你可以在里面玩构造函数来模仿这样的钩子。否则,使用一些自己的约定(例如,具有module_start
函数的插件会在dlopen
等之后调用dlopen
函数。)。
有些库正在将dlopen
包装到更高级别的东西中。例如,Qt有QPluginLoader& QLibrary等......
还有LD_PRELOAD trick(也许您可以通过这样的技巧重新定义自己的dlclose
& ifunc
,并让您修改的函数执行挂钩)。 dlopen
function attribute也可能相关。
由于Gnu Libc free software dlopen
提供{{1}} - 还有MUSL Libc,您可以修补它以满足您的需求。 dladdr(3)也很有用!
如果您正在为某些Objective-C创建自己的运行时,您应该熟悉使用该运行时的Objective-C编译器的约定,并且您可能拥有自己的模块加载器,而不是重载{{1}} ......