加载时动态链接库调度



我希望我的Windows应用程序能够引用封装在DLL中的一组广泛的类和函数,但在加载之前,我需要能够引导应用程序选择该DLL的正确版本。我熟悉使用dllexport/dlliport和生成导入库来实现加载时动态链接,但我似乎找不到任何关于可能在导入库本身中找到某种入口点函数的网站间信息,所以我可以,特别是,使用CPUID来检测主机CPU配置,并基于该信息做出加载奇偶DLL的决定。更具体地说,我想构建两个版本的DLL,一个是用/ARCH:AVX构建的,充分利用SSE-AVX指令,另一个是假设没有比SSE2更新的可用DLL。

一个要求:要么DLL必须在加载时链接,要么需要有一种超级简单的方法来手动绑定从DLL外部引用的函数,而且有很多,大部分都封装在类中。

额外的问题:由于我的库将是跨平台的,是否有一个基于Linux的共享对象的等价物?

我建议您尽可能避免从可执行文件中动态解析DLL,因为这只会让您的生活变得艰难,尤其是因为您有很多暴露的接口,而且它们不是纯C。

可能的解决方案

创建一个"选择器"进程,它提供必要的UI来决定您需要哪个DLL,或者它甚至可以自动确定它。让该进程将已决定的任何DLL移动到主可执行文件所期望的标准位置(和名称)。然后让选择器进程启动您的主可执行文件;它将从你的标准位置获取它的DLL,而不必知道那里有哪个版本的DLL。无延迟加载,无抖动,无额外编码;非常容易。

如果这对你来说不是一个选项,那么这里是延迟加载DLL的起点。这条路要崎岖得多。

Windows

  • LoadLibrary()以获取内存中的DLL:https://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx
  • GetProcAddress()获取指向函数的指针:https://msdn.microsoft.com/en-us/library/windows/desktop/ms683212(v=vs.85).aspx
  • 或者可能使用自定义辅助函数的特殊延迟加载DLL功能,尽管存在限制和潜在的行为变化。。我自己从未尝试过:https://msdn.microsoft.com/en-us/library/151kt790.aspx(由Igor Tandetnik提出,似乎合理)

Linux

  • dlopen()获取内存中的SO:http://pubs.opengroup.org/onlinepubs/009695399/functions/dlopen.html
  • dladdr()获取指向函数的指针:http://man7.org/linux/man-pages/man3/dladdr.3.html

要添加到qxyn的答案中,可以通过生成一个小型静态存根库来模拟Linux上的延迟加载,该库将在第一次调用任何函数时dlopen,然后将实际执行转发到共享库。这种存根库的生成可以通过自定义项目特定脚本或Implib.so:自动生成

# Generate stub
$ implib-gen.py libxyz.so
# Link it instead of -lxyz
$ gcc myapp.c libxyz.tramp.S libxyz.init.c

相关内容

  • 没有找到相关文章

最新更新