2024-08-15 09:00:00

API和ABI的区别

我是Linux系统编程的新手,在阅读时遇到了API和ABI Linux系统编程。

API的定义:

API定义了接口 一个软件进行通信 与另一个在源级。

ABI的定义:

而API定义了一个源 接口时,ABI定义了 两个之间的低级二进制接口 或者更多的软件 特定的体系结构。它定义了 应用程序如何与 本身,应用程序如何交互 与内核,以及如何一个 应用程序与库交互。

程序如何在源级进行通信?什么是源级别?它是否与源代码有关?或者库的源代码包含在主程序中?

我所知道的唯一区别是API主要由程序员使用,而ABI主要由编译器使用。


当前回答

这是我的外行解释:

API——考虑包含文件。它们提供编程接口。 ABI——想想内核模块。当你在某个内核上运行它时,它必须同意如何在没有包含文件的情况下进行通信,即作为低级二进制接口。

其他回答

我经常在api不兼容的更改或abi不兼容的更改的意义上遇到这些术语。

API更改本质上是使用以前版本编译的代码将不再工作。这可能是因为您向函数添加了参数,或者更改了在本地代码之外可访问的内容的名称。任何时候,当您更改一个头文件时,它就会迫使您更改.c/.cpp文件中的某些内容,您就做了一个api更改。

ABI更改是指已经根据版本1编译的代码将不再使用版本2的代码库(通常是库)。这通常比与api不兼容的更改更难跟踪,因为像向类添加虚拟方法这样简单的事情可能与ABI不兼容。

我发现了两种非常有用的资源,用于了解什么是ABI兼容性以及如何保存它:

在KDE项目中使用c++的做和不做的列表 Ulrich Drepper的《如何编写共享库》(glibc的主要作者)

API:应用程序接口

这是您从应用程序/库中公开的公共类型/变量/函数集。

在C/ c++中,这是在应用程序附带的头文件中公开的内容。

ABI:应用程序二进制接口

这就是编译器构建应用程序的方式。 它定义了一些东西(但不限于):

参数如何传递给函数(寄存器/堆栈)。 谁从堆栈中清除参数(调用方/被调用方)。 返回值的位置。 异常如何传播。

(应用二进制接口)结合操作系统的特定硬件平台的规范。它超越了API(应用程序程序接口),后者定义了从应用程序到操作系统的调用。ABI为特定的CPU系列定义API和机器语言。API不能确保运行时兼容性,但ABI可以,因为它定义了机器语言或运行时格式。

礼貌

API是人类使用的。我们编写源代码。当我们编写程序并想要使用一些库函数时,我们编写如下代码:

long howManyDecibels = 123L;
int ok = livenMyHills(howManyDecibels);

and we needed to know that there is a method livenMyHills(), which takes a long integer parameter. So as a Programming Interface it's all expressed in source code. The compiler turns this into executable instructions which conform to the implementation of this language on this particular operating system. And in this case result in some low level operations on an Audio unit. So particular bits and bytes are squirted at some hardware. So at runtime there's lots of Binary level action going on which we don't usually see.

在二进制级别,必须对在二进制级别传递的字节有一个精确的定义,例如4字节整数中的字节顺序,或者复杂数据结构的布局——是否有填充字节来对齐一些值。这个定义就是ABI。

这是我的外行解释:

API——考虑包含文件。它们提供编程接口。 ABI——想想内核模块。当你在某个内核上运行它时,它必须同意如何在没有包含文件的情况下进行通信,即作为低级二进制接口。