dlmopen和C ++库

问题描述 投票:1回答:1

(这可能是一个相当高级的问题,抱歉:-))

我有一个问题,我需要将一个插件(一个共享库)加载到一个应用程序中,但该插件可能使用一个二进制库,该二进制文件与应用程序使用的库版本不兼容。我的想法是使用dlmopen()并将插件加载到自己的命名空间中。我希望获得二进制不兼容库的两个单独副本(即使二进制兼容,也可以获得任何其他常见依赖性)。

这似乎在一定程度上起作用,但在某些情况下,我在glibc内部得到一个段错误,在调用静态对象的构造函数时(这是我用调试器发现的)。

我已经做了一个简单的例子来重现这个问题,可以在github上找到:https://github.com/mhier/segregatedLinkingExample

该示例使用libxml ++作为外部公共C ++库,因此您需要安装其开发包。运行“mk.sh”进行编译,然后运行“main”。它会崩溃(至少在Ubuntu 16.04和18.04上会崩溃)。如果删除“-DWITH_CRASH”,则不再崩溃。

WITH_CRASH编译开关允许在主可执行文件中使用libxml ++。它总是在插件库libC中使用。在主可执行文件和插件中只使用了libxml ++,我看到了崩溃。在此上下文中,“使用”与从中派生虚拟类一样少,并确保通过实现构造函数/析构函数来生成派生类的代码。它甚至没有在插件中执行代码(除了通过dl_init - >静态对象的构造函数等)。

我在互联网上找不到关于dlmopen的东西。我没有发现任何指向正确方向的错误报告。有没有人曾经使用dlmopen为C ++库创建一个新的命名空间?任何形式的输入如何从这一点继续是非常受欢迎的!

c++ linux plugins dynamic-loading
1个回答
1
投票

所以似乎答案不是这样做的。 dlmopen似乎与C ++有问题,可能导致未定义的行为。据推测,名称空间不能完全解决ODR违规问题。

我承认,这个答案是我的主观看法。我没有找到很多关于将dlmopen用于C ++库的好资源。因此,我的结论是不使用它,因为我需要它可靠地工作。我见过非常奇怪的效果,例如如果我将共享库与特定的第三方库链接(即使不使用它),我问题中的示例也会再次起作用。除非我能理解这些影响,否则我不相信解决方案(因为它可能只是意外地工作)。

dlmopen()可能在其他上下文中工作,例如如果一个控制应用程序和共享库,并可以测试它是否正确加载。

© www.soinside.com 2019 - 2024. All rights reserved.