【问题标题】:How can I make a shared library's symbols strong?如何使共享库符号强大?
【发布时间】:2016-12-07 21:06:38
【问题描述】:

我创建了一个共享库,它引用了很多 C++ 模板函数。这些符号作为弱引用输入到共享库的导出表中(例如,当我使用 nm 查看共享库的符号时,它们显示为类型 W)。这意味着在运行时,这些符号可能会被来自首先加载的不同共享库的副本插入。

我的共享库使用包含在库本身中的这些函数的副本,而不是来自任何其他库,这对我的应用程序很重要。有什么办法可以确保这一点?在我看来,这相当于将所有各种模板实例静态链接到共享库中。

【问题讨论】:

    标签: c++ linux shared-libraries


    【解决方案1】:

    这意味着在运行时,这些符号可能会被插入 通过从首先加载的不同共享库中复制。

    请注意,无论弱属性如何,它们都可以插入(请参阅this GCC post,它说动态链接器将弱点视为与强点类似,除非设置了LD_DYNAMIC_WEAK,但通常不会设置)。

    我的共享库对我的应用程序很重要 使用包含的这些功能的副本 在图书馆本身内,而不是来自任何其他图书馆。 有什么办法可以确保这一点?

    您可以做几件事。

    通常推荐的方法是将fvisibility=hidden 添加到您的CFLAGS 以防止从您的库中导出任何符号,然后用__attribute__((visibility("default"))) 标记(希望很少)导出的函数。这也将允许在编译时进行更好的优化并加快启动速度,因为 rtld 将需要处理更少的符号。

    穷人的有限解决方案是使用-fvisibility-inlines-hidden,这是-fvisility=hidden 的有限形式。它只会隐藏内联函数(例如来自 STL 模板的函数)。

    如果您不想弄乱源代码,请使用-Wl,-Bsymbolic 链接 - 这将强制尽可能在库中解析引用。

    -- 编辑--

    实际上,即使您启用 -fvisibility=hidden 以防止其他库(或可执行文件本身)动态插入库内对导出函数的引用,您也需要 -Bsymbolic

    【讨论】:

    • 谢谢。 -Bsymbolic 和/或 -Bsymbolic-functions 是我的问题的解决方案。不过,我想我可能会采用推荐的方法来严格定义公共 API 并使用-fvisibility=hidden。这似乎是最佳做法。
    • 再想一想,我认为即使使用-fvisibility=hidden,您也需要-Bsymbolic - 没有它,导出的函数可以被其他共享库插入。此外,为了避免与fvisibility=hidden 混淆,您可以使用它更简单的变体-fvisiblity-inlines-hidden - 这将隐藏所有内联函数(包括 STL 模板)。我已经更新了答案。
    猜你喜欢
    • 2011-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-07
    • 2011-02-11
    • 1970-01-01
    • 1970-01-01
    • 2020-02-08
    相关资源
    最近更新 更多