Application Binary Interface(ABI)

Application Binary Interface(ABI) 是指应用程序在二进制级别上的调用约定和数据布局规则。它决定了一个程序如何与操作系统、库或其他程序的二进制部分交互。ABI 是在编译后的程序之间的接口,而不是在源码层面的接口。


ABI 的主要内容

  1. 函数调用约定(Calling Conventions)
    定义了函数调用时:

    • 参数如何传递(通过寄存器还是栈)。
    • 返回值如何传递。
    • 函数调用前后由谁负责保存寄存器(调用者还是被调用者)。

    示例:

    • 在 x86 平台上,Windows 使用 stdcall,Linux 使用 cdecl
    • 参数的顺序和方法可能不同,比如先传递右边的参数还是左边的。
  2. 二进制符号(Symbol Naming)
    决定编译后的函数或变量符号在二进制文件中的命名规则。

    • C 的 ABI 通常直接使用函数名,例如 _add
    • C++ 的 ABI 通常会进行名称修饰(Name Mangling)以支持函数重载,例如 _Z3addii
  3. 数据类型的布局和对齐(Data Layout and Alignment)
    定义了:

    • 基本类型(如 intdouble)的大小。
    • 结构体和类的内存对齐规则。
    • 字节序(大端或小端)。
  4. 异常处理(Exception Handling)
    规定在不同模块或库之间如何传递和处理异常,特别是跨语言的异常。

  5. 动态链接(Dynamic Linking)
    描述动态链接库(如 .so.dll 文件)在加载和调用时的接口规则。


ABI 的作用

ABI 的核心作用是确保 二进制兼容性,即:

  • 不同的模块(如动态库和主程序)可以协同工作,即使它们是由不同编译器编译的。
  • 应用程序能够在某个硬件和操作系统平台上正常运行。

举例:C 和 C++ 的 ABI 差异

在 C 中:

int add(int a, int b) {
    return a + b;
}

生成的二进制符号可能是:_add

在 C++ 中:

int add(int a, int b) {
    return a + b;
}

生成的二进制符号可能是:_Z3addii(因为 C++ 支持函数重载,需要进行名称修饰)。

因此,C++ 函数如果需要被其他语言或工具调用,就必须使用 extern "C" 以禁用名称修饰,从而遵循 C 的 ABI。


ABI 的重要性

  • 跨语言调用:通过一致的 ABI,C 语言库可以被多种语言(如 Python、C#、Rust)调用。
  • 跨编译器兼容:遵循相同的 ABI,不同编译器生成的代码可以协同运行。
  • 动态链接库的使用:动态库通过 ABI 提供函数接口,供程序运行时调用。

总结

ABI 是程序运行时在二进制层面的契约,它规范了如何正确地调用函数、传递参数和处理数据,使得程序、库和系统可以无缝协作。
注意:该内容由由AIGC提供。

posted @ 2024-12-24 10:49  长空nice  阅读(9)  评论(0编辑  收藏  举报