664

ABIが何であるかを明確に理解したことがありません。ウィキペディアの記事を紹介しないでください。もし私がそれを理解することができれば、私はここにそのような長い投稿を投稿しないでしょう.

これは、さまざまなインターフェースに関する私の考え方です。

テレビのリモコンは、ユーザーとテレビの間のインターフェースです。これは既存のエンティティですが、それ自体では役に立ちません (機能を提供しません)。リモコンのこれらの各ボタンのすべての機能は、テレビ セットに実装されています。

インターフェイス:functionalityconsumerその機能の間の「既存のエンティティ」レイヤー です。インターフェイス自体は何もしません。背後にある機能を呼び出すだけです。

ユーザーが誰であるかに応じて、さまざまなタイプのインターフェイスがあります。

コマンド ライン インターフェイス (CLI)コマンドは既存のエンティティであり、コンシューマーはユーザーであり、機能は背後にあります。

functionality:このインターフェイスを説明している目的を解決する私のソフトウェア機能。

existing entities:コマンド

consumer:ユーザー

グラフィカル ユーザー インターフェイス (GUI)ウィンドウ、ボタンなどは既存のエンティティであり、消費者はユーザーであり、機能は背後にあります。

functionality:このインターフェイスを説明している問題を解決する私のソフトウェア機能。

existing entities:ウィンドウ、ボタンなど

consumer:ユーザー

アプリケーション プログラミング インターフェイス (API)関数 (より正確には) インターフェイス (インターフェイス ベースのプログラミング) は既存のエンティティであり、ここでのコンシューマーはユーザーではなく別のプログラムであり、機能はこのレイヤーの背後にあります。

functionality:このインターフェイスを説明している問題を解決する私のソフトウェア機能。

existing entities:関数、インターフェイス (関数の配列)。

consumer:別のプログラム/アプリケーション。

Application Binary Interface (ABI)ここから問題が始まります。

functionality:???

existing entities:???

consumer:???

  • 私はさまざまな言語でソフトウェアを作成し、さまざまな種類のインターフェイス (CLI、GUI、および API) を提供してきましたが、ABI を提供したことがあるかどうかはわかりません。

ウィキペディアは次のように述べています。

ABI は、次のような詳細をカバーします。

  • データ型、サイズ、配置。
  • 関数の引数がどのように渡され、戻り値が取得されるかを制御する呼び出し規則。
  • システム コール番号と、アプリケーションがオペレーティング システムに対してシステム コールを行う方法。

その他の ABI は、次のような詳細を標準化します。

  • C++ の名前マングリング、
  • 例外の伝播、および
  • 同じプラットフォーム上のコンパイラ間の呼び出し規約を呼び出しますが、クロスプラットフォームの互換性は必要ありません。
  • 誰がこれらの詳細を必要としますか? OSは言わないでください。私はアセンブリプログラミングを知っています。リンクと読み込みの仕組みを知っています。私は内部で何が起こっているかを正確に知っています。

  • C++ の名前マングリングが登場したのはなぜですか? バイナリレベルで話していると思いました。言語はなぜ入ってくるのですか?

とにかく、[PDF] System V Application Binary Interface Edition 4.1 (1997-03-18)をダウンロードして、正確に何が含まれているかを確認しました。うーん、ほとんど意味不明でした。

  • ELFファイル形式を説明するために 2 つの章 (第 4 および第 5) が含まれているのはなぜですか? 実際、この仕様の重要な章は 2 つだけです。残りの章は「プロセッサ固有」です。とにかく、それはまったく別のトピックだと思いました。ELF ファイル形式の仕様がABIであるとは言わないでください。定義によると、インターフェイスとしての資格はありません。

  • 私たちは非常に低いレベルで話しているので、それは非常に具体的でなければなりません。しかし、「命令セットアーキテクチャ(ISA)」固有の方法はわかりませんか?

  • Microsoft Windows の ABI はどこにありますか?

したがって、これらは私を悩ませている主要なクエリです。

4

17 に答える 17

707

「ABI」を理解する簡単な方法の 1 つは、「API」と比較することです。

API の概念については既に理解しています。たとえば、ライブラリや OS の機能を使用する場合は、API に対してプログラミングします。API は、外部コンポーネントの機能にアクセスするためにコードで使用できるデータ型/構造、定数、関数などで構成されています。

ABI は非常に似ています。API のコンパイル済みバージョン (または機械語レベルの API) と考えてください。ソース コードを記述するときは、API を介してライブラリにアクセスします。コードがコンパイルされると、アプリケーションは ABI を介してライブラリ内のバイナリ データにアクセスします。ABI は、コンパイルされたアプリケーションが (API が行ったのと同様に) 外部ライブラリにアクセスするために使用する構造とメソッドを、下位レベルでのみ定義します。API は、引数を関数に渡す順序を定義します。ABI は、方法の仕組みを定義します。これらの引数が渡されます (レジスタ、スタックなど)。API は、どの関数がライブラリの一部であるかを定義します。ABI は、ライブラリ ファイル内にコードを格納する方法を定義します。これにより、ライブラリを使用するすべてのプログラムが目的の関数を見つけて実行できるようになります。

外部ライブラリを使用するアプリケーションに関しては、ABI は重要です。ライブラリはコードやその他のリソースでいっぱいですが、プログラムはライブラリ ファイル内で必要なものを見つける方法を知っている必要があります。ABI はライブラリの内容をファイル内に格納する方法を定義し、プログラムは ABI を使用してファイルを検索し、必要なものを見つけます。システム内のすべてが同じ ABI に準拠している場合、作成者に関係なく、どのプログラムでもライブラリ ファイルを操作できます。Linux と Windows は異なる ABI を使用するため、Windows プログラムは Linux 用にコンパイルされたライブラリにアクセスする方法を知りません。

場合によっては、ABI の変更が避けられないことがあります。これが発生すると、そのライブラリを使用するプログラムは、新しいバージョンのライブラリを使用するように再コンパイルしない限り、機能しなくなります。ABI が変更されても API が変更されない場合、古いライブラリ バージョンと新しいライブラリ バージョンは「ソース互換」と呼ばれることがあります。これは、あるライブラリ バージョン用にコンパイルされたプログラムは他のバージョンでは動作しませんが、一方のライブラリ バージョン用に記述されたソース コードは、再コンパイルされた場合に別のバージョンで動作することを意味します。

このため、開発者は (混乱を最小限に抑えるために) ABI を安定させようとする傾向があります。ABI の安定性を維持するということは、関数インターフェイス (戻り値の型と数、型、および引数の順序)、データ型またはデータ構造の定義、定義された定数などを変更しないことを意味します。新しい関数とデータ型を追加することはできますが、既存のものはそのままにしておく必要があります。同じ。たとえば、ライブラリが関数のオフセットを示すために 32 ビット整数を使用していて、64 ビット整数に切り替えた場合、そのライブラリを使用するコンパイル済みのコードは、そのフィールド (またはそれに続くフィールド) に正しくアクセスしません。 . データ構造メンバーへのアクセスは、コンパイル中にメモリ アドレスとオフセットに変換され、データ構造が変更された場合、

非常に低レベルのシステム設計作業を行っている場合を除き、ABI は必ずしも明示的に提供するものではありません。(たとえば) C アプリケーションと Pascal アプリケーションは、コンパイル後に同じ ABI を使用できるため、言語固有でもありません。

編集:SysV ABI ドキュメントの ELF ファイル形式に関する章についての質問について: この情報が含まれている理由は、ELF 形式がオペレーティング システムとアプリケーション間のインターフェイスを定義するためです。OS にプログラムを実行するように指示すると、OS はプログラムが特定の方法でフォーマットされていることを期待し、(たとえば) バイナリの最初のセクションが特定のメモリ オフセットで特定の情報を含む ELF ヘッダーであることを期待します。これは、アプリケーションが自身に関する重要な情報をオペレーティング システムに伝える方法です。非 ELF バイナリ形式 (a.out や PE など) でプログラムをビルドすると、ELF 形式のアプリケーションを想定する OS は、バイナリ ファイルを解釈したり、アプリケーションを実行したりできなくなります。

IIRC、Windows は現在、Portable Executable (または PE) 形式を使用しています。そのウィキペディア ページの「外部リンク」セクションに、PE 形式に関する詳細情報へのリンクがあります。

また、C++ の名前マングリングに関する注意事項について: ライブラリ ファイルで関数を検索する場合、通常、関数は名前で検索されます。C++ では関数名をオーバーロードできるため、関数を識別するには名前だけでは不十分です。C++ コンパイラには、これを内部的に処理する独自の方法があり、名前マングリングと呼ばれます。ABI は、関数の名前をエンコードする標準的な方法を定義できるため、別の言語またはコンパイラで作成されたプログラムが必要なものを見つけることができます。C++ プログラムで を使用extern "c"すると、他のソフトウェアが理解できる標準化された名前の記録方法を使用するようコンパイラに指示することになります。

于 2010-03-16T18:04:28.433 に答える
166

アセンブリと OS レベルでの動作方法を知っている場合は、特定の ABI に準拠していることになります。ABI は、パラメーターがどのように渡されるか、戻り値がどこに配置されるかなどを管理します。多くのプラットフォームでは、選択できる ABI は 1 つだけです。そのような場合、ABI は単に「仕組み」です。

ただし、ABI は、クラス/オブジェクトが C++ でどのようにレイアウトされるかなども管理します。これは、モジュールの境界を越えてオブジェクト参照を渡すことができるようにする場合、または異なるコンパイラでコンパイルされたコードを混在させたい場合に必要です。

また、32 ビット バイナリを実行できる 64 ビット OS を使用している場合は、32 ビット コードと 64 ビット コードの ABI が異なります。

一般に、同じ実行可能ファイルにリンクするすべてのコードは、同じ ABI に準拠する必要があります。異なる ABI を使用してコード間で通信する場合は、何らかの形式の RPC またはシリアル化プロトコルを使用する必要があります。

さまざまな種類のインターフェイスを固定された一連の特性に絞り込もうとしていると思います。たとえば、インターフェイスは必ずしもコンシューマーとプロデューサーに分割する必要はありません。インターフェイスは、2 つのエンティティが相互作用するための規則にすぎません。

ABI は (部分的に) ISA に依存しない場合があります。一部の側面 (呼び出し規則など) は ISA に依存しますが、他の側面 (C++ クラス レイアウトなど) は依存しません。

明確に定義された ABI は、コンパイラを作成する人にとって非常に重要です。明確に定義された ABI がなければ、相互運用可能なコードを生成することは不可能です。

編集:明確にするためのいくつかのメモ:

  • ABI の「バイナリ」は、文字列またはテキストの使用を排除しません。C++ クラスをエクスポートする DLL をリンクする場合は、そのどこかでメソッドと型シグネチャをエンコードする必要があります。そこで、C++ の名前マングリングの出番です。
  • あなたが ABI を提供しなかった理由は、大多数のプログラマーが決して ABI を提供しないからです。ABI は、プラットフォーム (つまりオペレーティング システム) を設計するのと同じ人々によって提供され、広く使用されている ABI を設計する特権を持つプログラマはほとんどいません。
于 2010-01-31T09:50:47.260 に答える
85

次の場合は、実際にはABI はまったく必要ありません。

  • あなたのプログラムには関数がなく、そして--
  • プログラムは、単独で実行される単一の実行可能ファイル (つまり、組み込みシステム) であり、文字通り唯一実行されており、他と通信する必要はありません。

単純化しすぎた要約:

API: 「呼び出し可能な関数はすべてここにあります。」

ABI: 「これが関数の呼び出し方です。」

ABI は、適切に動作するようにプログラムをコンパイルするために、コンパイラとリンカーが準拠する一連の規則です。ABI は複数のトピックをカバーしています。

  • おそらく、ABI の最大かつ最も重要な部分は、「呼び出し規約」として知られるプロシージャ コールの標準です。呼び出し規約は、"関数" がアセンブリ コードに変換される方法を標準化します。
  • また、ABI は、ライブラリ内の公開された関数の名前をどのように表現するかを指示し、他のコードがそれらのライブラリを呼び出して、どの引数を渡す必要があるかを認識できるようにします。これを「ネームマングリング」と呼びます。
  • ABI は、使用できるデータ型の種類、データ型をどのように配置する必要があるか、およびその他の低レベルの詳細も規定します。

私が ABI の中核であると考えている呼び出し規約を詳しく見てみましょう。

機械自体に「機能」という概念はありません。関数を c のような高級言語で記述すると、コンパイラは のようなアセンブリ コードの行を生成します_MyFunction1:。これはlabelで、最終的にアセンブラによってアドレスに解決されます。このラベルは、アセンブリ コード内の「関数」の「開始」を示します。高レベルのコードでは、その関数を「呼び出す」ときに、実際に行っていることは、CPU をそのラベルのアドレスにジャンプさせ、そこで実行を継続させることです。

ジャンプの準備として、コンパイラは一連の重要なことを行う必要があります。呼び出し規約は、コンパイラがこれらすべてを行うために従うチェックリストのようなものです。

  • まず、コンパイラは、現在のアドレスを保存するために少しのアセンブリ コードを挿入します。これにより、「関数」が完了すると、CPU は適切な場所に戻って実行を継続できます。
  • 次に、コンパイラはアセンブリ コードを生成して引数を渡します。
    • 一部の呼び出し規約では、引数を (もちろん特定の順序で) スタックに置く必要があります。
    • 他の規則では、引数を特定のレジスタに配置する必要があります (もちろん、データ型によって異なります)。
    • さらに他の規則では、スタックとレジスタの特定の組み合わせを使用する必要があります。
  • もちろん、以前にこれらのレジスターに重要なものがあった場合、それらの値は上書きされて永久に失われるため、呼び出し規則によっては、引数をレジスターに入れる前にコンパイラーがそれらのレジスターの一部を保存する必要がある場合があります。
  • ここで、コンパイラは、以前に作成したラベルに移動するように CPU に指示するジャンプ命令を挿入します ( _MyFunction1:)。この時点で、CPU は「機能」の「中に」あると考えることができます。
  • 関数の最後に、コンパイラは、CPU に戻り値を正しい場所に書き込ませるアセンブリ コードを配置します。呼び出し規則は、戻り値を特定のレジスター (タイプに応じて) に入れるか、スタックに入れるかを決定します。
  • さあ、掃除の時間です。呼び出し規約によって、コンパイラがクリーンアップ アセンブリ コードを配置する場所が決まります。
    • 一部の規則では、呼び出し元がスタックをクリーンアップする必要があるとされています。これは、「関数」が実行され、CPU が以前の場所にジャンプした後、次に実行されるコードは非常に具体的なクリーンアップ コードである必要があることを意味します。
    • 他の規則では、クリーンアップ コードの一部の特定の部分は、ジャンプ バックの前に「関数」の最後に配置する必要があります。

多くの異なる ABI / 呼び出し規約があります。主なものは次のとおりです。

  • x86 または x86-64 CPU (32 ビット環境) の場合:
    • CDECL
    • STDCALL
    • ファーストコール
    • ベクトルコール
    • このSCALL
  • x86-64 CPU (64 ビット環境) の場合:
    • SYSTEMV
    • MSネイティブ
    • ベクトルコール
  • ARM CPU (32 ビット) の場合
    • AAPCS
  • ARM CPU (64 ビット) の場合
    • AAPCS64

これは、さまざまなABI用にコンパイルしたときに生成されるアセンブリの違いを実際に示す素晴らしいページです。

言及すべきもう 1 つのことは、ABI が関連するのはプログラムの実行可能モジュール内だけではないということです。また、プログラムがライブラリ関数を正しく呼び出すことを確認するために、リンカによっても使用されます。コンピューターで複数の共有ライブラリを実行していて、コンパイラがそれぞれが使用する ABI を認識している限り、スタックを爆発させることなくそれらから関数を適切に呼び出すことができます。

ライブラリ関数を呼び出す方法をコンパイラが理解していることは非常に重要です。ホストされたプラットフォーム (つまり、OS がプログラムをロードするプラットフォーム) では、プログラムはカーネル呼び出しを行わずに点滅することさえできません。

于 2016-12-30T20:40:46.243 に答える
21

アプリケーションバイナリインターフェイス(ABI)はAPIに似ていますが、ソースコードレベルで呼び出し元が関数にアクセスすることはできません。バイナリ表現のみがアクセス可能/利用可能です。

ABIは、プロセッサアーキテクチャレベルまたはOSレベルで定義できます。ABIは、コンパイラのコード生成フェーズが従うべき標準です。この規格は、OSまたはプロセッサのいずれかによって修正されています。

機能性:実装言語または特定のコンパイラー/リンカー/ツールチェーンに依存しない関数呼び出しを行うためのメカニズム/標準を定義します。JNIやPython-Cインターフェースなどを可能にするメカニズムを提供します。

既存のエンティティ:マシンコード形式の機能。

コンシューマー:別の関数(別の言語の関数、別のコンパイラーによってコンパイルされた関数、または別のリンカーによってリンクされた関数を含む)。

于 2010-03-23T06:07:56.487 に答える
12

機能:コンパイラ、アセンブリライタ、リンカ、およびオペレーティングシステムに影響を与える一連のコントラクト。コントラクトは、関数のレイアウト方法、パラメーターの受け渡し方法、パラメーターの受け渡し方法、関数が機能を返す方法を指定します。これらは通常、(プロセッサアーキテクチャ、オペレーティングシステム)タプルに固有です。

既存のエンティティ:パラメータレイアウト、関数セマンティクス、レジスタ割り当て。たとえば、ARMアーキテクチャには多数のABI(APCS、EABI、GNU-EABI、過去の事例を気にしないでください)があります。混合ABIを使用すると、境界を越えて呼び出すときにコードが機能しなくなります。

コンシューマー:コンパイラー、アセンブリー・ライター、オペレーティング・システム、CPU固有のアーキテクチャー。

誰がこれらの詳細を必要としますか?コンパイラ、アセンブリライター、コード生成(またはアライメント要件)を実行するリンカー、オペレーティングシステム(割り込み処理、syscallインターフェイス)。アセンブリプログラミングを行った場合は、ABIに準拠していました。

C ++の名前マングリングは特殊なケースであり、リンカーと動的リンカー中心の問題です。名前マングリングが標準化されていない場合、動的リンクは機能しません。以降、C++ABIはまさにC++ABIと呼ばれます。これはリンカーレベルの問題ではなく、コード生成の問題です。C ++バイナリを取得すると、ソースから再コンパイルせずに、別のC ++ ABI(名前マングリング、例外処理)と互換性を持たせることはできません。

ELFは、ローダーとダイナミックリンカーを使用するためのファイル形式です。ELFは、バイナリコードとデータのコンテナ形式であり、コードのABIを指定します。PE実行可能ファイルはABIではないため、厳密な意味でELFをABIとは見なしません。

すべてのABIは命令セット固有です。ARM ABIは、MSP430またはx86_64プロセッサでは意味がありません。

WindowsにはいくつかのABIがあります。たとえば、fastcallとstdcallは2つの一般的なABIです。システムコールABIもまた異なります。

于 2010-03-23T06:26:25.150 に答える
10

少なくともあなたの質問の一部に答えさせてください。Linux ABI がシステムコールに与える影響と、それが役立つ理由の例を示します。

システムコールは、ユーザー空間プログラムがカーネル空間に何かを要求する方法です。呼び出しの数値コードと引数を特定のレジスタに入れ、割り込みをトリガーすることで機能します。カーネル空間への切り替えが発生すると、カーネルは数値コードと引数を検索し、要求を処理し、結果をレジスターに戻し、ユーザー空間への切り替えをトリガーします。これは、たとえば、アプリケーションがメモリを割り当てたり、ファイルを開いたりする場合に必要です (システムコール "brk" および "open")。

現在、システムコールには「brk」などの短い名前と対応するオペコードがあり、これらはシステム固有のヘッダー ファイルで定義されています。これらのオペコードが同じままである限り、再コンパイルすることなく、異なる更新されたカーネルで同じコンパイル済みユーザーランド プログラムを実行できます。したがって、プリコンパイルされたバイナリ、つまり ABI で使用されるインターフェイスがあります。

于 2010-01-31T09:50:18.747 に答える
8

概要

ABI (アプリケーション バイナリ インターフェイス) を定義する正確なレイヤーについては、さまざまな解釈と強い意見があります。

私の見解では、ABI は、特定の API の与えられた/プラットフォームと見なされるものの主観的な慣習です。ABI は、特定の API に対して「変更されない」規則、またはランタイム環境 (エグゼキューター、ツール、リンカー、コンパイラー、jvm、および OS) によって対処される規則の「残りの部分」です。

インターフェイスの定義: ABI、API

joda-time のようなライブラリを使用する場合は、依存関係を宣言する必要がありますjoda-time-<major>.<minor>.<patch>.jar。ライブラリはベスト プラクティスに従い、セマンティック バージョニングを使用します。これにより、API の互換性が次の 3 つのレベルで定義されます。

  1. パッチ - コードをまったく変更する必要はありません。ライブラリはいくつかのバグを修正するだけです。
  2. マイナー - コードを変更する必要はありません。
  3. メジャー - インターフェイス (API) が変更され、コードの変更が必要になる場合があります。

同じライブラリの新しいメジャー リリースを使用するためには、他の多くの規則を引き続き尊重する必要があります。

  • ライブラリに使用されるバイナリ言語 (Java の場合は、Java バイトコードを定義する JVM ターゲット バージョン)
  • 呼び出し規約
  • JVM 規則
  • リンク規則
  • 実行時の規則 これらはすべて、使用するツールによって定義および管理されます。

Java のケーススタディ

たとえば、Java はこれらすべての規則をツールではなく、正式な JVM 仕様で標準化しました。この仕様により、他のベンダーは、互換性のあるライブラリを出力できるさまざまなツール セットを提供できるようになりました。

Java は、ABI に関する 2 つの興味深いケース スタディを提供します。Scala バージョンとDalvik仮想マシンです。

Dalvik 仮想マシンが ABI を壊した

Dalvik VM には、Java バイトコードとは異なるタイプのバイトコードが必要です。Dalvik ライブラリは、Java バイトコード (同じ API) を Dalvik 用に変換することによって取得されます。このようにして、同じ API の 2 つのバージョンを取得できます: 元の によって定義されていjoda-time-1.7.2.jarます。joda-time-1.7.2.jarとと呼ぶことができますjoda-time-1.7.2-dalvik.jar。彼らは、スタック指向の標準 Java VM 用の別の ABI を使用します。Oracle のもの、IBM のもの、オープン Java などです。2 番目の ABI は Dalvik 周辺のものです。

Scala の連続リリースは互換性がない

Scala には、Scala のマイナー バージョン間でバイナリ互換性がありません: 2.X . このため、同じ API "io.reactivex" %% "rxscala" % "0.26.5" には、Scala 2.10、2.11、および 2.12 用の 3 つのバージョン (将来的にはさらに追加) があります。変更点 今のところわかりませんが、バイナリには互換性がありません。おそらく最新バージョンでは、古い仮想マシンでライブラリを使用できなくするもの、おそらくリンク/命名/パラメータ規則に関連するものが追加されています。

Java の連続したリリースは互換性がありません

Java には、JVM のメジャー リリース (4、5、6、7、8、9) でも問題があります。下位互換性のみを提供します。Jvm9-targetは、他のすべてのバージョン用にコンパイル/ターゲット (javac のオプション) されたコードを実行する方法を知っていますが、JVM 4 は JVM 5 をターゲットにしたコードを実行する方法を知りません。この非互換性は、さまざまなソリューションのおかげでレーダーの下を飛んでいます。

  1. セマンティック バージョニング: ライブラリが上位の JVM を対象とする場合、通常はメジャー バージョンを変更します。
  2. JVM 4 を ABI として使用すれば安全です。
  3. Java 9 では、特定のターゲット JVM のバイトコードを同じライブラリに含める方法に関する仕様が追加されています。

API 定義から始めたのはなぜですか?

API と ABI は、互換性を定義する方法に関する規則にすぎません。下位層は、多数の高レベルのセマンティクスに関して一般的です。そのため、いくつかの規則を簡単に作成できます。最初の種類の規則は、メモリ アラインメント、バイト エンコーディング、呼び出し規則、ビッグ エンディアン エンディアン エンディアン エンコーディングなどに関するものです。それらの上に、他の記述と同様の実行可能規則、リンク規則、Java で使用されるような中間バイト コード、またはGCC で使用される LLVM IR。3 番目に、ライブラリーの見つけ方、それらのロード方法に関する規則を取得します (Java クラスローダーを参照)。概念がどんどん高くなるにつれて、当然のことと見なす新しい規則が生まれます。それが、彼らがセマンティック バージョニングに到達しなかった理由です。バージョン。でセマンティック バージョニングを修正でき<major>-<minor>-<patch>-<platform/ABI>ます。これはすでに実際に起こっていることです: プラットフォームはすでに , rpm, dll( jarJVM バイトコード), war(jvm+web サーバー), apk, 2.11(特定の Scala バージョン) などです。APK と言うとき、すでに API の特定の ABI 部分について話していることになります。

API は別の ABI に移植可能

抽象化の最上位 (最上位の API に対して記述されたソースは、他の下位レベルの抽象化に再コンパイル/移植できます。

rxscala のソースがいくつかあるとします。Scala ツールが変更された場合は、それに合わせて再コンパイルできます。JVM が変更された場合、高レベルの概念に煩わされることなく、古いマシンから新しいマシンへの自動変換を行うことができます。移植は難しいかもしれませんが、他のクライアントには役立ちます。まったく異なるアセンブラ コードを使用して新しいオペレーティング システムを作成する場合、トランスレータを作成できます。

言語間で移植された API

リアクティブ ストリームのように、複数の言語に移植された API があります。一般に、特定の言語/プラットフォームへのマッピングを定義します。API は人間の言語または特定のプログラミング言語で正式に定義されたマスター仕様であると私は主張します。他のすべての「マッピング」は、ある意味で ABI であり、通常の ABI よりも多くの API です。REST インターフェイスでも同じことが起こっています。

于 2017-04-22T15:39:50.920 に答える
3

呼び出しが確実に成功するように、ABI は呼び出し元と呼び出し先の間で一貫している必要があります。スタック使用、レジスタ使用、ルーチン終了時のスタック ポップ。これらはすべて、ABI の最も重要な部分です。

于 2010-01-31T09:42:07.377 に答える
2

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

ABI-アプリケーション、ライブラリ、OS などの 2 つのバイナリ部分間の実行時Application Binary Interfaceのマシン コード通信に関するもので、オブジェクトがメモリに保存される方法、関数が呼び出される方法 ( )、マングリングなどについて説明します。ABIcalling convention

API と ABI の良い例は、Swift 言語を使用した iOS エコシステムです

  • Application layer- 異なる言語を使用してアプリケーションを作成する場合。たとえば、 [Swift と Objective-C の混合] を使用してアプリケーションを作成できSwiftますObjective-C

  • Application - OS layer- ランタイム - OS の一部であり、Swift runtime各バンドル (アプリ、フレームワークなど) に含めることはできません。Objective-Cが使用するのと同じですstandard libraries

  • Library layer-Module Stabilityケース -コンパイル時-別のバージョンの Swift コンパイラで構築されたフレームワークをインポートできます。これは、別のバージョンのコンパイラ ( [About].swiftinterfaceで使用される) によって消費されるクローズド ソース (ビルド前) のバイナリを作成するのが安全であることを意味します。.swiftmodule

    Module compiled with _ cannot be imported by the _ compiler
    //or
    Compiled module was created by a newer version of the compiler
    
  • Library layer-Library Evolutionケース

    1. コンパイル時間 - 依存関係が変更された場合、クライアントを再コンパイルする必要はありません。
    2. ランタイム - システム ライブラリまたは動的フレームワークは、新しいものによってホットスワップできます。

[API 対 ABI]
[Swift モジュールとライブラリの安定性]

于 2019-12-10T15:52:02.540 に答える
1

要するに、哲学では、ある種類のものだけがうまくやっていくことができ、ABI は、ソフトウェアが連携して動作するようなものと見なすことができます。

于 2010-02-26T15:50:29.423 に答える