11

假设下面的头文件对应,例如一个共享库。导出的函数采用指向此标头中定义的自定义结构的指针:

// lib.h

typedef struct {
  char c;
  double d;
  int i;
} A;

DLL_EXPORT void f(A* p);

如果共享库是使用一个编译器构建的,然后从另一个编译器构建的 C 代码中使用,则它可能由于内存对齐方式不同而无法工作,正如C-structs 中的内存对齐所暗示的那样。那么,有没有办法让我的结构定义在同一平台上的不同编译器之间可移植?

我对 Windows 平台特别感兴趣(显然它没有明确定义的 ABI),但也很想了解其他平台。

4

3 回答 3

13

TL; DR 在实践中你应该没问题。

C 标准没有定义这一点,但平台 ABI 通常会定义。也就是说,对于给定的 CPU 架构和操作系统,可以定义 C 如何映射到允许不同编译器互操作的程序集。

结构对齐并不是平台 ABI 必须定义的唯一内容,您还有函数调用约定和类似的东西。

C++ 使它变得更加复杂,ABI 必须指定 vtable、异常、名称修改等。

在 Windows 上,我认为有多个 C++ ABI,具体取决于编译器,但 C 大多在编译器之间兼容。我可能是错的,不是 Windows 专家。

一些链接:

无论如何,底线是您正在寻找平台/编译器 ABI 规范中的保证,而不是 C 标准。

于 2012-04-24T13:20:44.320 回答
4

唯一确定的方法是查阅相关编译器的文档。但是,通常情况下,C 结构布局(如您所说,位域除外)由您正在使用的环境的 ABI 描述定义,并且 C 编译器将倾向于遵循本机 ABI。

于 2012-04-24T13:22:29.607 回答
1

不仅没有保证,而且即使您使用相同的编译器,由于构建中使用的编译器开关不同,或者如果您使用相同编译器和相同开关的不同版本(发生在嵌入式编译器中,我从事)。

您需要确保结构的表示完全相同,使用开关、#pragmas,无论编译器为您提供什么。

我的建议 - 完全远离这个。在函数中传递您的参数,而不是包装在结构中。

即使以这种简单的形式,如果您处理两个编译器,这也不是微不足道的。例如,您需要确保 int 采用相同数量的字节。同样调用 conevntion - 参数顺序 - 从左到右或从右到左 - 编译器之间可能会有所不同。

于 2012-04-24T13:20:35.093 回答