mac os x为动态加载提供了一个有用的库,称为dyld。动态加载处理的许多有趣的函数中,有一些函数允许安装回调,dyld将在加载或卸载映像时调用回调,分别由dlopen
和dlclose
。这些函数分别是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文件。
那么,有没有一个等效于dyld库的linux。或者,至少,在任何linux库中,这两个函数_dyld_register_func_for_add_image
和_dyld_register_func_for_remove_image
是等价的吗?或者,我必须自己实现这两个版本,这并不难,但我必须找到一种方法,使dlopen
和dlclose
调用回调函数,只要它们被调用。
编辑
为了让事情更清楚,我需要创建一个库,它有一个回调函数,只要dlopen
动态加载外部库,就必须调用该函数。我的回调函数必须对任何动态加载的库执行某些操作。
最佳答案
是的,它被称为dlopen(3)使用-ldl
标准库
更准确地说:
使用-fPIC
标记编译插件的源代码,以获得独立于位置的代码对象文件*.pic.o
通过链接gcc -shared
您的*.pic.o
文件(您还可以链接另一个共享库),制作一个共享库插件。
使用GCC function attributes,特别是constructor
和destructor
函数(或具有显式构造函数和析构函数的静态C++数据,因此命名)。在插件的__attribute__((constructor))
时间内调用dlopen
的函数,在插件的__attribute__((destructor))
时间内调用dlclose
的函数
当插件调用主程序中的某些函数时,将主程序与-rdynamic
属性链接是非常有用和必要的。
不要忘记声明extern "C"
你的C++插件函数(程序需要的)
在主程序中使用dlsym
来获取插件中的函数或数据地址。
确实没有像dlopen
那样的_dyld_register_func_for_add_image
钩子。您可能需要使用构造函数和/或dl_iterate_phdr(3)来模拟它。
如果您可以更改插件(您dlopen
的共享对象),您可以在其中玩构造函数技巧来模拟此类挂钩。否则,请使用一些自己的约定(例如,具有module_start
函数的插件将获得在module_start
之后调用的dlopen
函数等等)。
有些库将dlopen
包装成更高级别的内容。例如qt有QPluginLoader&QLibrary等。
还有LD_PRELOAD trick(也许您可以通过这样一个技巧重新定义自己的dlopen
&dlclose
,并让您修改的函数执行钩子操作)。ifunc
function attribute也可能是相关的。
由于Gnu Libc是free software提供的dlopen
-还有MUSL Libc,您可以根据需要对其进行修补。dladdr(3)也可能有用!
补遗
如果您正在为某个objective-c创建自己的运行时,您应该很好地了解使用该运行时的objective-c编译器的约定,并且您可能可以拥有自己的模块加载程序,而不是重载dlopen
。
关于linux - Linux是否有与dyld相当的产品?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15703569/