我一直在寻找一种在 Linux 上创建共享库(让我们将库命名为 libbar.so
)延迟加载 的方法,希望在 的帮助下实现它链接器,不修改用 C++ 编写的源代码上的任何内容;我的意思是我不想调用 dlopen()
也不dlsym()
在父库的源代码中(我们将其命名为 libfoo.so
)调用 libbar.so
的函数因为它们使源代码变得困惑并且维护过程变得困难。 (简而言之,我希望即使在 Linux 上也能采用与 Visual Studio 的 /DELAYLOAD
选项类似的方式)
无论如何,到目前为止,我在互联网上发现了一些与我的问题相关的不确定信息,因此,如果您能就以下问题得到大家的回答,以明确信息,那将是非常好的。
- GNU ld 是否支持 Linux 上的任何延迟加载机制?
- 如果没有,Clang 怎么样?
- 是
dlopen()
family 是在 Linux 上延迟加载共享库的唯一方法吗?
我测试通过了 -zlazy
带有库路径的 GCC (g++) 标志,它似乎接受了标志,但行为看起来并不像 libbar.so
延迟加载(没有 libbar.so
,我期待在第一次调用 libbar.so
时出现异常,但实际上在进入 libfoo.so
之前引发了异常)。另一方面,Clang ( clang++
) 留下了一个警告,它忽略了选项标志。
最好的问候,
最佳答案
延迟加载不是运行时功能。 MSVC++ 在没有 Windows 帮助的情况下实现了它。就像 dlopen
是 Linux 上的唯一方法一样,GetProcAddress
是 Windows 上唯一的运行时方法。
那么,什么是延迟加载呢?这非常简单:对 DLL 的任何调用都必须通过一个指针(因为您不知道它将加载到哪里)。这一直由编译器和链接器为您处理。但是对于延迟加载,MSVC++ 最初将此指针设置为一个为您调用 LoadLibrary
和 GetProcAddress
的 stub 。
Clang 可以在没有 ld
帮助的情况下做同样的事情。在运行时,它只是一个普通的 dlopen
调用,Linux 无法确定是 Clang 插入了它。
关于c++ - 如何在 Linux 上延迟加载共享库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23403848/