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

时间:2014-05-06 03:28:24

标签: c++ linux gcc clang

如果您有真正经验与上述标题相关,您是否介意留下您的评论?我试图让一个共享对象在Ubuntu上延迟加载Clang和GCC(我实际上不介意使用哪个编译器),但它们看起来并不支持任何延迟加载功能(我预计延迟加载功能将一个存根放在一个父对象中,该对象试图在需要功能的时刻根据需要加载另一个对象,但实际上并没有这样做。以下命令显示我试图使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上,公民也希望梦想拥有延迟加载功能,这将是一种自然的反应。如果你对我的感受有任何评论,我也会感激。

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

无论如何,非常感谢你。

2 个答案:

答案 0 :(得分:11)

这更像是运行时链接程序ld-linux.so提供的功能问题。

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

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

由于这个原因,如果库不包含预期的符号,您可以在程序开始运行后很好地获得“未定义的符号”错误,但是如果库完全丢失,则在程序启动之前会出现错误

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

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

你可能想要寻找一个好的插件框架 - 参考参考:

答案 1 :(得分:0)

Linux不支持开箱即用的延迟加载库,但它可以使用在Windows上使用的相同机制轻松实现,即通过首先连接File "/usr/lib64/python2.7/subprocess.py", line 568, in check_output process = Popen(stdout=PIPE, *popenargs, **kwargs) File "/usr/lib64/python2.7/subprocess.py", line 711, in __init__ errread, errwrite) File "/usr/lib64/python2.7/subprocess.py", line 1327, in _execute_child raise child_exception OSError: [Errno 2] No such file or directory 主要共享库的小存根静态库打电话给它的任何功能。

您可以通过为您的项目量身定制的自定义脚本手动实现此类存根库,或使用Implib.so自动生成它:

dlopen