Linux:C++抽象类作为共享对象API
Linux: C++ Abstract class as shared object API
我阅读了这篇关于C++DLL API-s的文章。"C++成熟方法:使用抽象接口"是否也适用于使用不同编译器(使用不同编译器编译的exe和.so)的linux?我在网上找不到任何对linux系统进行确认/否认的东西。在这篇文章中,作者说它适用于windows,因为COM技术可以与其他编译器配合使用。
要理解这个问题,请至少阅读文章的"C++成熟方法"一章。
是和否
无法保证不同的编译器会以相同的方式在返回的接口类中实现虚拟函数调用——如果是这样的话,它将灾难性地失败(或者会悄悄地破坏东西……甚至更有趣)。但如果我正确地调用了-现代g++、clang和linux上的intel似乎以相同的方式处理它,因此应该在这个级别上是可互操作的。
然而,还有一个问题没有在文章中提及,这适用于linux和windows。如果你采取这种方法,只有你可以传递的东西是
- 接口
- 像int这样的简单类型
- 小心控制内存中布局的类型
这意味着您的接口中不能有像void withVector(std::vector<int> v)
这样的函数,因为编译器的不同标准库可能会对向量的内部进行不同的布局。事实上,这可能在编译器版本、标准库版本之间发生变化,甚至在编译器设置中也会发生变化。
因此,您需要创建一个封装std::vector
的IIntVector
,然后使用withVector(IIntVector& v)
。
如果您传递或返回自己的任何非接口类,则可能会遇到同样的问题。
在一个老例子中,我在编译单元之间传递boost::shared_ptr
,在一种情况下,类中有一个锁成员,而在另一种情况中不存在锁——这意味着对象具有不同的预期大小,并导致(静默)堆栈损坏。整个开发团队都很开心。
我发现在双方之间使用纯C桥,并在C++中提供一个DLL创建者可以构建和使用的实用程序层来调用纯C桥是不容易出错的。但即使在C中,它也不是微不足道的。
在C的情况下,你仍然需要注意编译器设置引起的数据结构的变化(但这种情况更为罕见),你还需要注意一个编译器不会像另一个编译器那样在你的结构中插入填充。
- 处理影响跨不同线程共享对象的定时回调的最佳方法是什么?
- 如何创建一个共享对象与另一个.所以在Cmake
- 内联函数的函数本地静态对象是否在共享对象文件之间共享?
- 在 Android Studio 中使用 C++ 共享对象时出现问题
- 共享对象、符号、C/C++ 库链接和加载
- ./main:加载共享库时出错:libopencv_highgui.so.4.0:无法打开共享对象文件:没有这样的文件或
- 在 win32 上生成 R 包:无法加载共享对象 (.dll)
- 共享对象中的符号
- sf::Windows上的音乐:api-ms-win-crt-locale-l1-1-0.dll:无法打开共享对象文件
- C++ 为什么要级联共享对象链接
- 加载共享库时出错:libbsoncxx.so._noabi:无法打开共享对象文件:没有此类文件或目录
- 从单个.cpp构建共享对象
- 与 32 位共享对象的链接问题
- 卸载共享对象(.so 文件)在 C++ 中用 dlopen() 打开
- 运行程序时找不到共享对象库,但在编译过程中链接了它
- 错误:无法打开共享对象文件:没有此类文件或目录
- Qt 创建器:将库移动到 subdir 后无法打开共享对象文件
- 共享对象中的符号名称与文件中.cpp函数不同
- C++:在共享对象中调用抽象基类构造函数/未定义的符号
- Cython:共享对象中未定义的符号