c - 当在 DLL 或 .so 中调用函数时,当编译器使用对齐和填充进行自己的结构布局时,为什么传递结构是可靠的?

标签 c struct

c 语言结构中的 AFAIK 会按照编译器认为合适的方式进行布局、对齐和填充。这就是为什么你不能依赖一个 c 程序来使用来自另一个 c 程序的结构。例如。您不能将结构保存为另一个 c 程序将读取并转换为同一个结构的二进制文件。您也许可以使用这样的打包结构,但这并不是一个很好的做法。
所以我很惊讶地发现 .so 和 DLL 文件具有将复杂结构(其引用)作为参数的 c 函数。至少我公司的产品是这样做的。
这是可靠的,这是好的做法吗?是否有一些大小、对齐和填充都相同的结构布局的新标准?
我知道 64 位程序不能调用 32 位库,但我仍然认为结构布局可能因相同位的编译器而异。

最佳答案

对于给定的处理器类型和给定的操作系统,通常有一个标准 ABI (application binary interface)它指定了以下内容:

  • 整数类型的宽度和字节序。
  • 浮点类型的宽度和表示。
  • 对齐约束,它决定了结构中填充的存在。
  • 参数如何传递给函数(在寄存器和堆栈中)。

  • 例如,在 x86_64处理器架构(即 64 位 PC 的处理器架构),有两种流行的 ABI:Microsoft x64 calling convention ,在 Windows 上使用,以及 System V amd64 ABI ( PDF — 您具体询问的部分在第 3.1 节“机器接口(interface)”中),在其他任何地方都可以使用。 32 位 x86 历史上有更多的碎片。
    因此,通常,如果您在默认模式下为同一平台(处理器和操作系统)使用不同的编译器,它们将为结构生成相同的布局,并且它们将生成与其他编译器编译函数的方式兼容的函数调用代码阅读他们的论点。当您混合不同平台时会出现问题,例如在嵌入式设备上编写结构并尝试在 PC 上读取它。

    关于c - 当在 DLL 或 .so 中调用函数时,当编译器使用对齐和填充进行自己的结构布局时,为什么传递结构是可靠的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68642759/

    相关文章:

    c++ - 是否有 OpenCL 2.2 功能在 OpenCL C++ 中可用,但在 OpenCL C 中不可用?

    c - 找到许多子数组的开始和结束的算法?

    c - 如何使用 C(不是 C++)在结构的所有实例中拥有一个 const 成员?

    c++ - 为什么我的 vector 不能访问嵌套结构中的变量?

    c - 返回结构

    c - 在 C 中定义位字段时的输出行为

    c - xcode 恢复以前的版本?

    pointers - 如何将 lParam 转换为多个结构?

    c - C中具有不同数据类型的二维数组

    c++ - QList 模板化结构