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

Linux: C++ Abstract class as shared object API

本文关键字:共享 对象 API C++ 抽象类 Linux      更新时间:2023-10-16

我阅读了这篇关于C++DLL API-s的文章。"C++成熟方法:使用抽象接口"是否也适用于使用不同编译器(使用不同编译器编译的exe和.so)的linux?我在网上找不到任何对linux系统进行确认/否认的东西。在这篇文章中,作者说它适用于windows,因为COM技术可以与其他编译器配合使用。

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

是和否

无法保证不同的编译器会以相同的方式在返回的接口类中实现虚拟函数调用——如果是这样的话,它将灾难性地失败(或者会悄悄地破坏东西……甚至更有趣)。但如果我正确地调用了-现代g++、clang和linux上的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的情况下,你仍然需要注意编译器设置引起的数据结构的变化(但这种情况更为罕见),你还需要注意一个编译器不会像另一个编译器那样在你的结构中插入填充。