用不同的C ++编译器构建的二进制文件和库如何兼容?

你好

编译器在生成的代码中有很大的自由度。他们在实现VTable,RTTI,异常等等方面具有完全的自由。即使是非常基本的东西,例如指针的大小,函数的调用方式和名称修饰也可以任意选择,而与操作系统和体系结构无关。

但是,我从未遇到过在任何操作系统(Android,Linux,Mac OS,Windows),任何体系结构(x86,x86-)上使用任何编译器(Clang,GCC,ICC,MSVC)编译C ++程序的问题。 64,ARM)并将其链接到使用其他编译器构建的库。

所有二进制文件如何与其他文件兼容?

运行时链接程序或类似文件会动态地使二进制文件“适应”吗?

编译器是否同意某些标准?如果是这样,我在哪里可以找到有关这些二进制级别的事实标准的信息?

黑暗原子

通常,它们是不兼容的。以下是一些不兼容的地方:

不同的数据类型大小

例如,GCC为a使用16个字节long double,而VS将其别名为double(8个字节)。有关更多信息,请检查

如果两种尺寸都已知,则可以轻松解决此问题,因为在尺寸之间进行转换是微不足道的(但可能会导致精度损失)。

改名

这可能是最知名的问题。C ++编译器需要修饰符号,以便(在很多情况下)函数重载是可能的。没有标准的名称处理方案,因此编译器会选择它们自己的名称,这会导致不兼容,因为例如使用VS编译的代码可能无法识别使用GCC甚至是VS早期版本编译的库中的名称。

可以通过不修饰名称并将其导出为未修饰的C函数来解决此问题。但是,这意味着必须将类方法包装在C函数中才能导出它们(因为C无法理解类),这实际上并不方便。

Visual C ++名称处理方案

GCC名称修改方案

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何制作使用 openmp 并使用 intel 的 C 编译器编译的二进制文件?

相同的代码和相同的编译器可以在不同的机器上生成不同的二进制文件吗?

使用相同编译器标志的不同 Makefile 会生成不同的二进制文件

使用不同的软件包和构建标签构建多个二进制文件

C ++编译器如何区分令牌>>用于二进制运算符和模板

C ++编译器如何用二进制代码表示int数字?

如何在Linux上的C库中使用已编译的二进制文件?

如何找出用于构建二进制文件的* .c和* .h文件?

在python扩展中为C和C ++文件使用不同的编译器标志

ldd:找不到用于xl c编译二进制文件的库,但可以在AIX上找到gcc编译二进制文件的库

我在C中使用AES加密和解密txt文件时使用不同的二进制文件

正确的方式包含与预编译的二进制文件和手动编译的二进制文件不同的头文件

为 VS 构建时,如何在调试和发布之间在 CMake 中指定不同的二进制文件

为什么 gcc 会为使用不同形式的整数文字的程序生成不同的编译二进制文件?

c# 如何使用不同的签名(?)

从C程序构建新的二进制文件

“ C ++编译器使用二进制对象布局”这句话的含义和用途是什么

如何从Android中的本机编译C ++二进制文件访问相机

简单的方法来保证C ++库和C链接的二进制兼容性?

从单个C源代码生成库和二进制文件

VS2010和VS2012之间的二进制C ++库兼容性?

如何编写Shell脚本,以便在编译C ++程序时将二进制文件放入二进制目录

C# - 浏览文件夹和二进制阅读器

如何在C ++中使用混合文本和二进制文件读取大文件

如何使用使用不同选项构建的C#和C ++库创建Nuget包?

使用不同的编译器构建Bazel

在C ++中从文件读取ASCII和二进制

符号链接会发生什么?原始二进制文件和符号二进制文件的行为不同

如何为多个C ++二进制文件启用地址清理器