目前我正在尝试实现一个ELF共享库,使用-static-libstdc++
和-static-libgcc
选项构建。这个共享库必须用C11构建,它有一些遗留代码,此外,它有一个非常具体的设计。
如果一些应用程序链接这个共享库,它们的C实用程序一定不能互相干扰。例如,与std::cout
相关的std::ios_base::Init::Init()
(_ZNSt8ios_base4InitC1Ev
)等待出现在两个独立的实现中,一个是针对该特定共享库的静态实现,另一个是针对应用程序及其其他共享库的共享实现。然而,LD_DEBUG=all
的使用表明,这个特定的共享库的C实用程序符号,如std::ios_base::Init::Init()
,绑定到libstdc++
中定义的符号,我试图避免...
这样的逻辑是否可以实现,或者至少可以以某种方式解决?在任何情况下,我都需要单独的C实用程序。先谢谢你了!
1条答案
按热度按时间syqv5f0l1#
目前我正在尝试实现一个ELF共享库,使用
-static-libstdc++
和-static-libgcc
选项构建。最好的办法是不要这样做--“正常”地链接你的库(所以它依赖于
libstdc++.so.6
和libgcc_s.so.1
),这样你的大部分问题都会消失。(参见http://xyproblem.info-- * 为什么 * 要静态链接libstdc++
?)但是,
LD_DEBUG=all
的使用表明,这个特定共享库的C++实用程序符号(如std::ios_base::Init::Init()
)绑定到libstdc++
中定义的符号当您有两个
libstdc++
副本时,这句话就毫无意义了--一个在您的库中,另一个在“库外”(可能是libstdc++.so.6
)。你的意思是,你的库中对
std::ios_base::Init::Init()
的引用被绑定到libstdc++.so.6
内部的定义。你可以通过隐藏库中的所有符号来避免这种情况,并且使用链接器脚本只暴露“官方”接口。参见this answer。
注意事项:
libstdc++
“隐藏”在你的共享库中,并通过接口传递C++
对象(例如astd::string
或std::map
),您可以预期各种~不可能调试的问题,由于ABI之间的“隐藏”libstdc++.a
和外部libstdc++.so.6
不兼容。