c++ - Clang/GCC 真的支持延迟加载功能吗?

标签 c++ linux gcc clang

如果您有真实经历与上述标题相关的内容,您是否介意对此发表评论?我试图在 Ubuntu 上使用 Clang 和 GCC 延迟加载一个共享对象(我实际上不介意使用哪个编译器),但它们看起来并不真正支持任何延迟加载功能(我期望延迟加载功能在父对象中放置一个 stub ,该对象试图在需要功能时按需加载另一个对象,但实际上并没有)。以下命令显示我试图将 libbar.so 延迟加载到 libfoo.so:

clang bar.c -fPIC -shared -o libbar.so
clang foo.c -Wl,-zlazy,lL'/path/to/where/lib/is',-lbar -o foo

如果 libbar.so 不存在,您将看到 libfoo.so 在进入条目之前引发异常。不管怎样,我不介意上面的命令是否有错别字,但想知道Clang/GCC 是否真的支持延迟加载功能

但是,就我个人而言,如果 Clang/GCC 不支持任何延迟加载功能,我无法相信是否要求 Linux 程序开发人员调用 dlopen() 或 dlsym() 来延迟加载共享对象。如果对象是用C写的还好,但是如果是用C++写的,那情况就完全复杂了:(

我相信在编译器或链接器的帮助下实现的解决方案是最好的,因为我已经在 Windows 和 Mac OS 上成功地完成了它。所以我觉得如果公民希望即使在 Clang/GCC 上也有延迟加载功能,那将是一种自然的 react 。如果您对我的感受有任何评论,我也将不胜感激。

附言。我知道 Solaris 支持延迟加载功能,但这不适合我,因为我不会在其上开发任何东西。

无论如何,非常感谢您。

最佳答案

这更多是运行时链接器提供的功能问题,ld-linux.so .

此链接器确实支持符号的延迟绑定(bind),但不支持库的延迟加载。这意味着当程序启动时,可执行文件所需的每个共享对象都会加载,但程序中的符号在首次引用它们之前不会解析为加载的库。

这样做的原因是性能。一个库可能包含数千个函数符号,这些符号在程序的单次执行中永远不会被调用。解决所有问题将是浪费时间。

因此,如果一个库不包含预期的符号,您可能会在程序开始运行后很长时间内收到“ undefined symbol ”错误,但如果一个库完全缺失,您将在程序启动前收到错误.

您引用的 -zlazy 选项仅控制惰性符号绑定(bind)。事实上它是默认启用的(至少对于 GCC,我没有检查 clang)。

在程序启动后加载库的唯一方法,例如响应某些命令行选项、配置或其他动态条件,是调用 dlopen .

您可能想四处寻找一个好的插件框架 - 引用资料请参阅:

关于c++ - Clang/GCC 真的支持延迟加载功能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23485489/

相关文章:

c++ - 从ID3D11DeviceChild::GetDevice()方法获取设备

c++ - 内部类和初始化

c++ - Boost.spirit代码。编译错误

c++ - 为什么 C++ 中不允许从 int (*)(int) 到 void* 的 static_cast ?

gcc - ELF文件中的共享库绝对路径

linux - 对基于 Linux 的 SOAP Web 服务服务器的建议

php - 将网页 (html) 转换为缩略图/预览以通过 PHP 文件输出

Linux grep命令

c++ - 在 AT&T 内联汇编中将 float / double 设置为常量值

从结构体中的函数指针调用函数