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

问题描述 投票:5回答:2

如果您真的经历过与上述标题相关的事情,您是否介意留下您对此的评论?我试图让一个共享对象在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支持延迟加载功能,但这不适合我,因为我不会在其上开发任何东西。

无论如何,非常感谢你提前。

c++ linux gcc clang
2个回答
11
投票

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

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

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

因此,如果库不包含预期的符号,则在程序开始运行后可能会出现“未定义的符号”错误,但如果完全丢失库,则在程序启动之前会出现错误。

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

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

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


0
投票

Linux不支持开箱即用的库的延迟加载,但它可以使用在Windows上使用的相同机制轻松实现,即通过链接到小型存根静态库,dlopens主要共享库首次调用它的任何功能。

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

$ clang bar.c -fPIC -shared -o libbar.so
$ implib-gen.py libbar.so
$ clang foo.c libbar.tramp.S libbar.init.c -o foo
© www.soinside.com 2019 - 2024. All rights reserved.