2024-08-15 09:00:00

API和ABI的区别

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

API的定义:

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

ABI的定义:

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

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

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


当前回答

API -应用程序编程接口是一个编译时接口,开发人员可以使用它来使用源代码中的库、操作系统、核心调用等非项目功能

ABI[关于]-应用程序二进制接口是一个运行时接口,由程序在执行期间用于机器代码中的组件之间的通信

其他回答

让我举一个具体的例子,说明在Java中ABI和API是如何不同的。

ABI不兼容的更改是如果我将方法a# m()从将字符串作为参数更改为String…论点。这不是ABI兼容的,因为您必须重新编译调用它的代码,但它是API兼容的,因为您可以通过重新编译来解析它,而无需在调用方中更改任何代码。

这里有一个例子。我的Java库有类A

    // Version 1.0.0
    public class A {
        public void m(String string) {
            System.out.println(string);
        }
    }

我有一个类使用这个库

    public class Main {
        public static void main(String[] args) {
            (new A()).m("string");
        }
    }

现在,库作者编译了他们的类A,我编译了我的类Main,一切都运行得很好。想象一个新版本的a出现了

    // Version 2.0.0
    public class A {
        public void m(String... string) {
            System.out.println(string[0]);
        }
    }

如果我只是使用新编译的类A,并将其与之前编译的类Main一起删除,那么在试图调用该方法时就会得到异常

Exception in thread "main" java.lang.NoSuchMethodError: A.m(Ljava/lang/String;)V
        at Main.main(Main.java:5)

如果我重新编译Main,这是固定的,所有工作再次。

您的程序(源代码)可以使用提供适当API的模块进行编译。

您的程序(二进制)可以在提供适当ABI的平台上运行。

API限制了类型定义、函数定义、宏,有时还有库应该公开的全局变量。

ABI限制了一个“平台”应该为您的程序运行提供什么。我喜欢从三个层面来考虑:

处理器级——指令集,调用约定 内核级——系统调用约定,特殊的文件路径约定(例如Linux中的/proc和/sys文件),等等。 操作系统级别——对象格式、运行时库等。

考虑一个名为arm-linux-gnueabi-gcc的交叉编译器。“arm”表示处理器架构,“linux”表示内核,“gnu”表示其目标程序使用gnu的libc作为运行时库,不同于arm-linux-androideabi-gcc使用Android的libc实现。

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

礼貌

这是我的外行解释:

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

API -应用程序编程接口是一个编译时接口,开发人员可以使用它来使用源代码中的库、操作系统、核心调用等非项目功能

ABI[关于]-应用程序二进制接口是一个运行时接口,由程序在执行期间用于机器代码中的组件之间的通信