Linux:C ++抽象类作为共享对象API

时间:2015-07-02 00:03:29

标签: c++ linux shared-libraries

我在C ++ DLL API上阅读this article。 " C ++成熟的方法:使用抽象接口"还使用不同的编译器在linux上工作(exe和.so用不同的编译器编译)?我无法在网上找到任何确认/否认它的Linux系统。在文章中,作者说它适用于Windows,因为COM技术可以与其他编译器一起使用。

要理解这个问题,请至少阅读" C ++成熟方法"文章的章节。

1 个答案:

答案 0 :(得分:2)

是和否。

不能保证不同的编译器会以相同的方式在返回的接口类中实现虚函数调用 - 如果是这种情况那么它将会灾难性地失败(或者会无声地破坏东西......甚至更多乐趣)。但是,如果我正确地重复 - 现代g ++,linux上的clang和intel似乎以同样的方式处理它,因此应该在这个级别上可互操作。

然而,文章中没有提到进一步的问题,这适用于linux和windows。如果采用这种方法,只能你能传递的东西是

  1. interfaces
  2. 简单类型,如int
  3. 您仔细控制内存布局的类型。
  4. 这意味着您不能在界面中使用void withVector(std::vector<int> v)这样的函数,因为编译器的不同标准库可能会以不同方式布局向量的内部。事实上,这可以在编译器版本,标准库版本甚至编译器设置之间进行更改。

    因此,您需要创建一个包裹IIntVector的{​​{1}},然后使用std::vector

    如果您传递或返回自己的任何非接口类,则可能会遇到相同的问题。

    一个古老的例子,这就是我在编译单元之间传递withVector(IIntVector& v),其中一个锁定成员在类中,另一个没有锁定存在 - 这意味着对象具有不同的预期大小和导致(沉默)堆栈损坏。为整个开发团队带来乐趣。

    我发现在双方之间使用纯C桥并且在C ++中提供了一个实用程序层,DLL创建者可以构建和使用调用纯C桥的实用程序层。但即使在C中它也不是微不足道的。

    在C情况下,你仍然需要注意由编译器设置引起的数据结构的变化(但它们很少见),你还需要注意一个编译器不会在你的结构中插入填充。另一个没有。