244

私は Linux システム プログラミングは初めてで、 Linux System Programmingを読んでいるときに API と ABI に出会いました。

API の定義:

API は、あるソフトウェアがソース レベルで別のソフトウェアと通信するためのインターフェイスを定義します。

ABIの定義:

API はソース インターフェイスを定義しますが、ABI は特定のアーキテクチャ上の 2 つ以上のソフトウェア間の低レベル バイナリ インターフェイスを定義します。アプリケーションがそれ自体と対話する方法、アプリケーションがカーネルと対話する方法、およびアプリケーションがライブラリと対話する方法を定義します。

プログラムはソースレベルでどのように通信できますか? ソースレベルとは?それは何らかの形でソースコードに関連していますか? または、ライブラリのソースがメイン プログラムに含まれますか?

私が知っている唯一の違いは、API は主にプログラマーによって使用され、ABI は主にコンパイラーによって使用されることです。

4

11 に答える 11

367

API: アプリケーション プログラム インターフェイス

これは、アプリケーション/ライブラリから公開するパブリック タイプ/変数/関数のセットです。

C/C++ では、これは、アプリケーションと共に出荷するヘッダー ファイルで公開するものです。

ABI: アプリケーション バイナリ インターフェイス

これは、コンパイラがアプリケーションを構築する方法です。
それは以下のものを定義します (ただし、これらに限定されません):

  • パラメーターが関数に渡される方法 (レジスター/スタック)。
  • スタックからパラメーターを消去するのは誰ですか (呼び出し元/呼び出し先)。
  • return の戻り値が配置される場所。
  • 例外の伝播方法。
于 2010-09-24T06:25:42.753 に答える
60

API は人間が使用するものです。ソースコードを書きます。プログラムを書き、何らかのライブラリ関数を使用したい場合、次のようなコードを書きます。

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

livenMyHills()そして、長い整数パラメーターを取るメソッドがあることを知る必要がありました。したがって、プログラミング インターフェイスとして、すべてソース コードで表現されます。コンパイラはこれを、この特定のオペレーティング システムでのこの言語の実装に準拠する実行可能な命令に変換します。この場合、Audio ユニットで低レベルの操作が行われます。そのため、特定のビットとバイトが一部のハードウェアで噴出されます。そのため、実行時には、通常は見られない多くのバイナリ レベルのアクションが実行されます。

于 2010-09-24T05:29:19.657 に答える
54

これらの用語は、ほとんどの場合、API と互換性のない変更、または ABI と互換性のない変更という意味で出くわします。

API の変更は基本的に、以前のバージョンでコンパイルされたはずのコードが機能しなくなる場所です。これは、関数に引数を追加したか、ローカル コードの外部でアクセス可能なものの名前を変更したために発生する可能性があります。ヘッダーを変更し、.c/.cpp ファイルの何かを変更する必要がある場合はいつでも、API を変更したことになります。

ABI の変更は、バージョン 1 に対して既にコンパイルされているコードがバージョン 2 のコードベース (通常はライブラリ) では機能しなくなる場所です。クラスに仮想メソッドを追加するのと同じくらい単純なことは ABI と互換性がない可能性があるため、これは一般に、API と互換性のない変更よりも追跡するのが難しいです。

ABI の互換性とは何か、およびそれを維持する方法を理解するための 2 つの非常に役立つリソースを見つけました。

于 2010-09-24T06:32:05.750 に答える
26

これは私の素人の説明です:

  • API - ファイルを考えてincludeください。これらはプログラミング インターフェイスを提供します。
  • ABI - カーネル モジュールを考えてみてください。一部のカーネルで実行する場合、インクルード ファイルを使用せずに、つまり低レベルのバイナリ インターフェイスとして通信する方法について合意する必要があります。
于 2010-09-24T05:28:43.307 に答える
9

Java で ABI と API がどのように異なるか、具体的な例を挙げましょう。

ABI 非互換の変更は、メソッド A#m() を引数Stringとして取ることからString...引数に変更した場合です。これは、それを呼び出しているコードを再コンパイルする必要があるため、ABI 互換ではありませんが、呼び出し側でコードを変更せずに再コンパイルすることで解決できるため、API 互換です。

ここに例を示します。クラスAのJavaライブラリがあります

// 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)

メインを再コンパイルすると、これは修正され、すべてが再び機能します。

于 2017-02-22T16:08:01.723 に答える