我可以使用 dlopen() 和RTLD_NOW延迟加载共享库。但是一旦库被动态加载,我仍然需要使用 dlsym 单独加载每个符号。
由于我的库包含大量 API,我不想为所有 API 调用 dlsym。有什么方法可以使 API 以与正常加载时链接相同的方式工作(您只需调用 API 而无需 dlsym)?
我可以使用 dlopen() 和RTLD_NOW延迟加载共享库。但是一旦库被动态加载,我仍然需要使用 dlsym 单独加载每个符号。
由于我的库包含大量 API,我不想为所有 API 调用 dlsym。有什么方法可以使 API 以与正常加载时链接相同的方式工作(您只需调用 API 而无需 dlsym)?
您可能正在寻找 RTLD_GLOBAL。
从您链接到的页面[1]:
RTLD_GLOBAL
The symbols defined by this library will be made available for
symbol resolution of subsequently loaded libraries.
通过使用它,您应该能够围绕您的 API 创建一个不需要使用 dlsym() 的“包装器”库,从而减少所需的 dlsym() 调用总数。这当然提出了一个问题,即维护包装库是否比清理 API 更费力。
正如这里所解释的,你可以有一个插件,它包含一个函数,attribute(constructor)
将许多插件函数注册到主程序提供的一些全局数据结构中(因为插件的构造函数在插件时被调用dlopen
)。所以你可以dlopen
-ed 一个插件,甚至不使用dlsym
一次来检索和使用(许多)插件功能。
我需要使用 dlsym 单独加载每个符号。
错误的。dlsym
通过符号(或名称)查找函数(或数据)。该功能已经在这里(因为插件的整个代码段都通过添加到您的虚拟地址空间中dlopen
)。
可能不再相关,但仍然 - 您正在寻找 Windows DLL 导入库的模拟,这些库将为您的代码提供看起来像普通函数但在内部调用的dlopen
存根dlsym
。
Linux 不提供开箱即用的导入库,但您可以手动生成它们,通过一些自定义脚本或使用Implib.so工具来完全自动地执行此操作。