具有C 接口的C 动态库如何在不同的编译器版本之间不会破坏ABI
How can a C++ dynamic library with a C++ interface not break ABI between different compiler versions?
最近,我一直在为我的爱好3D图形引擎项目使用Assimp库来加载3D型号。
库以DLL的形式出现,并附有导入库(LIB)和EXP文件(仅在最新来源构建时;我知道它具有有关导出功能的信息,类似于LIB)
现在,让我提出这个问题的惊喜部分是:
我能够正确地使用任何构建/链接错误或运行时错误使用库的两个不同版本的C 接口:
- 预先构建的库,版本
3.1.1
,该库是构建并取决于较旧的运行时(MSVCP110.DLL
,MSVCR110.DLL
)(我后来决定更改为自己的构建,因为该二进制构建中存在链接错误) - 我自己由VS 2013编译器制成的源构建,具体取决于
MSVCP120.DLL
和VCRUNTIME120.DLL
我能够将这两个库二进制文件与我的可执行二进制文件一起使用:
:- vs 2013编译器
- vs 2015编译器
我惊讶地使用图书馆的成功,如上所述,没有任何错误,是由:
引起的。- 在Internet上阅读有关C 库和接口如何在不同编译器版本之间不兼容(ABI),因此无法与其他编译器构建的二进制文件一起使用。例外:通过C界面的用法,可以保持ABI兼容性;com库(构建COM接口是为了克服同一问题)。
- 使用使用不同编译器构建的二进制文件可能会因为功能名称操作而引起问题(可能由导入库解决吗?!),动态内存分配和由分配器/destructors的不同版本完成的动态内存分配和释放。
任何人都可以就我成功地使用VS 2013构建的动态库以及VS 2015 Toolset应用程序而没有任何上述问题的VS 2013构建的动态库,也可以提供一些有关此用例的见解?另外,当使用VS 2013构建和VS 2015构建我的3D引擎应用程序时,使用预构建的二进制文件时也适用。这是孤立的情况,还是Assimp库本身负责这些问题,并以这种方式实施以确保兼容性?
库的实际用法非常简单:我使用了进口商对象(类)的局部堆栈变量,并从那里从那里进行了操纵并从一堆结构中读取信息;没有其他类(我认为)
只要DLL中使用的所有类和内存都在类内分配,释放和维护,并且您不使用界面边界上的标准库容器对象,您就完全是安全地做。
如果模块使用不同的编译器,甚至使用不同的CRT使用情况,或者至少使用了不同的CRT,则甚至不允许在DLL边界上使用Std:String。
。实际上,使用普通接口(纯虚拟类)对于所有VS C 编译器都是安全的。也使用外部" C"很安全。
因此,如果您交换的结构只是豆荚或具有简单的普通数据对象,并且只要在DLL内部进行分配和破坏,则可以自由混合并使用不同的编译器构建DLL。
。最好的例子是Windows OS的DLL。他们使用了简单数据结构的明确定义的接口。内存管理和分配(例如Windows,Menus,GDI对象)是通过透明的手柄完成的。DLL只是您的黑框。
希望我能遇到所有积分。
- 特征版本 3.2.0 和 3.3.4 之间的数值差异
- 为什么库API+编译器ABI足以确保具有不同版本gcc的对象之间的兼容性
- 检测到 Conan 配置文件设置与 CMake 之间的编译器版本不匹配
- 为什么C++中的表达式类型在不同版本之间会发生变化
- 为什么CRC计算在C和C 版本之间有所不同
- 两个提升版本之间的冲突
- .vcxproj 和 .vcxproj.filters 中的工具版本之间的差异
- boost::v1.59 和 v1.60 之间的序列化存档版本
- g++-8 和早期版本之间的奇怪行为
- 如何在两个版本之间从perforce差异获取C/C 函数名称
- 具有C 接口的C 动态库如何在不同的编译器版本之间不会破坏ABI
- GLIBCXX(libstdc++.so.6)与gcc版本之间的关系
- 游戏"Life"中发布和调试版本之间的加速比例奇怪
- 最新版本的提升和提升几何库 (GGL) 之间的冲突
- 是否可以有一个零成本assert(),这样代码就不必在调试和发布版本之间进行修改
- 如何在不同的MS Office版本之间进行C 应用程序切换
- 如何在本机C++(Windows 7及以前版本)和通用C++(Windows 8及以后版本)应用程序之间共享代码
- 版本之间定义的实现
- C++版本之间的差异
- 调试版本和发布版本之间可能出现的差异