【问题标题】:Linux: C++ Abstract class as shared object APILinux:作为共享对象 API 的 C++ 抽象类
【发布时间】:2015-07-02 00:03:29
【问题描述】:

我在 C++ DLL API-s 上阅读了 this article。 “C++ 成熟方法:使用抽象接口”是否也适用于具有不同编译器的 Linux(使用不同编译器编译的 exe 和 .so)?我在网上找不到任何可以确认/拒绝 linux 系统的东西。在文章中作者说它适用于 windows,因为 COM 技术适用于其他编译器。

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

【问题讨论】:

    标签: c++ linux shared-libraries


    【解决方案1】:

    是和不是。

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

    但是,还有一个本文没有提到的问题,这适用于 linux 和 windows。如果你采用这种方法,只有你可以传递的东西是

    1. 接口
    2. int 等简单类型
    3. 需要仔细控制内存布局的类型。

    这意味着你的界面中不能有像void withVector(std::vector<int> v) 这样的函数,因为编译器的不同标准库可能会以不同的方式布局向量的内部结构。事实上,这可以在编译器版本、标准库版本甚至编译器设置之间发生变化。

    因此,您需要创建一个包装 std::vectorIIntVector,然后使用 withVector(IIntVector& v)

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

    一个老例子,我在编译单元之间传递boost::shared_ptr,在一种情况下,锁成员在类中,在另一种情况下不存在锁 - 这意味着对象具有不同的预期大小并导致(静默)堆栈损坏。为整个开发团队带来乐趣。

    我发现在两端之间使用纯 C 桥接器并提供 C++ 中的实用程序层,DLL 创建者可以构建和使用调用纯 C 桥接器的实用程序层不太容易出错。但即使在 C 中,这也不是微不足道的。

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

    【讨论】:

      猜你喜欢
      • 2011-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-20
      • 2017-03-20
      • 1970-01-01
      • 2015-02-28
      • 1970-01-01
      相关资源
      最近更新 更多