与STL相关的C ++ ABI问题

时间:2014-05-29 11:26:09

标签: c++ stl abi

我在搜索网络时,没有任何结论性的答案来解决与缺少C ++ ABI相关的问题,当涉及到在Windows中的dll边界导出c ++类时。

我可以使用extern c并为库提供类似api的c,但我希望最终用户能够使用我们stl容器的类。

您使用哪些通用模式以安全的方式导出跨dll边界使用stl容器的类?例如最佳实践。

这个问题适用于经验丰富的图书馆作者。

此致 Niladri

2 个答案:

答案 0 :(得分:2)

没有定义的C ++ ABI,在内存布局,名称修改,RTL等方面,编译器之间的确存在差异。

然而,它变得更糟糕了。例如,如果您的目标是MSVC编译器,那么您的dll / exe可以使用不同的宏构建,这些宏将STL配置为不包括迭代器检查,以便更快。这会修改STL类的布局,并且在链接时最终会破坏单一定义规则(ODR)(但链接仍然成功)。如果ODR被违反,那么你的程序似乎会随机崩溃。

我建议您阅读不完整的C ++,其中有一章关于C ++ ABI的主题。

结果是:

  • 你专门为将要链接到它的目标编译器编译dll并适当地命名dll(就像boost那样)。在这种情况下,您无法避免ODR违规,因此库的用户必须能够使用不同的选项自行重新编译库。
  • 提供便携式C API并提供C ++包装类,以方便在API的客户端编译。这是耗时但便携的。

答案 1 :(得分:2)

看看CppComponents https://github.com/jbandela/cppcomponents

您可以在不同的编译器中跨dll边界导出类和接口。

该库只是标题,因此无需构建。要使用它,您将需要MSVC 2013和/或GCC 4.8,因为它广泛使用C ++ 11可变参数模板。

请参阅C ++ Now中的演示文稿

https://github.com/boostcon/cppnow_presentations_2014/blob/master/files/cppnow2014_bandela_presentation.pdf?raw=true

https://github.com/jbandela/cppcomponents_cppnow_examples有演示文稿中的示例。