Saya baru mengenal pemrograman sistem linux dan saya menemukan API dan ABI saat membaca Pemrograman Sistem Linux .
Definisi API:
API mendefinisikan antarmuka tempat satu perangkat lunak berkomunikasi satu sama lain di tingkat sumber.
Definisi ABI:
Sedangkan API mendefinisikan antarmuka sumber, ABI mendefinisikan antarmuka biner tingkat rendah antara dua atau lebih perangkat lunak pada arsitektur tertentu. Ini mendefinisikan bagaimana suatu aplikasi berinteraksi dengan dirinya sendiri, bagaimana suatu aplikasi berinteraksi dengan kernel, dan bagaimana suatu aplikasi berinteraksi dengan perpustakaan.
Bagaimana suatu program berkomunikasi pada tingkat sumber? Apa itu level sumber? Apakah ini terkait dengan kode sumber? Atau sumber perpustakaan disertakan dalam program utama?
Satu-satunya perbedaan yang saya tahu adalah API sebagian besar digunakan oleh programmer dan ABI sebagian besar digunakan oleh kompiler.
Jawaban:
API adalah apa yang digunakan manusia. Kami menulis kode sumber. Ketika kita menulis sebuah program dan ingin menggunakan beberapa fungsi perpustakaan kita menulis kode seperti:
dan kami perlu tahu bahwa ada metode
livenMyHills()
, yang membutuhkan parameter integer panjang. Jadi sebagai Antarmuka Pemrograman semuanya dinyatakan dalam kode sumber. Kompiler mengubah ini menjadi instruksi yang dapat dieksekusi yang sesuai dengan implementasi bahasa ini pada sistem operasi khusus ini. Dan dalam hal ini menghasilkan beberapa operasi tingkat rendah pada unit Audio. Jadi bit dan byte tertentu disemprotkan ke beberapa perangkat keras. Jadi pada saat runtime ada banyak aksi tingkat Biner terjadi yang biasanya tidak kita lihat.sumber
API: Antarmuka Program Aplikasi
Ini adalah sekumpulan tipe / variabel / fungsi publik yang Anda paparkan dari aplikasi / perpustakaan Anda.
Dalam C / C ++ ini adalah apa yang Anda paparkan dalam file header yang Anda kirimkan dengan aplikasi.
ABI: Antarmuka Biner Aplikasi
Beginilah cara kompiler membangun aplikasi.
Ini mendefinisikan hal-hal (tetapi tidak terbatas pada):
sumber
Saya kebanyakan menemukan istilah-istilah ini dalam arti perubahan yang tidak kompatibel dengan API, atau perubahan yang tidak kompatibel ABI.
Perubahan API pada dasarnya adalah tempat kode yang dikompilasi dengan versi sebelumnya tidak akan berfungsi lagi. Ini bisa terjadi karena Anda menambahkan argumen ke suatu fungsi, atau mengubah nama sesuatu yang dapat diakses di luar kode lokal Anda. Setiap kali Anda mengubah header, dan itu memaksa Anda untuk mengubah sesuatu dalam file .c / .cpp, Anda telah membuat perubahan API.
Perubahan ABI adalah tempat kode yang telah dikompilasi dengan versi 1 tidak akan lagi berfungsi dengan versi 2 dari basis kode (biasanya perpustakaan). Ini umumnya lebih sulit untuk melacak daripada perubahan yang tidak kompatibel dengan API karena sesuatu yang sederhana seperti menambahkan metode virtual ke kelas dapat ABI tidak kompatibel.
Saya telah menemukan dua sumber yang sangat berguna untuk mencari tahu apa kompatibilitas ABI itu dan bagaimana cara melestarikannya:
sumber
Ini adalah penjelasan awam saya:
include
file. Mereka menyediakan antarmuka pemrograman.sumber
Linux shared library minimal runnable API vs contoh ABI
Jawaban ini telah diekstraksi dari jawaban saya yang lain: Apa itu antarmuka biner aplikasi (ABI)? tetapi saya merasa bahwa itu langsung menjawab yang satu ini juga, dan bahwa pertanyaan itu bukan duplikat.
Dalam konteks perpustakaan bersama, implikasi paling penting dari "memiliki ABI stabil" adalah bahwa Anda tidak perlu mengkompilasi ulang program Anda setelah perpustakaan berubah.
Seperti yang akan kita lihat dalam contoh di bawah ini, adalah mungkin untuk memodifikasi ABI, program yang rusak, meskipun API tidak berubah.
main.c
mylib.c
mylib.h
Kompilasi dan berjalan dengan baik dengan:
Sekarang, misalkan untuk v2 perpustakaan, kami ingin menambahkan bidang baru untuk
mylib_mystrict
dipanggilnew_field
.Jika kami menambahkan bidang sebelumnya
old_field
seperti pada:dan membangun kembali perpustakaan tetapi tidak
main.out
, maka pernyataan itu gagal!Ini karena baris:
telah menghasilkan perakitan yang mencoba mengakses yang pertama
int
dari struct, yang sekarangnew_field
bukan yang diharapkanold_field
.Karenanya perubahan ini mematahkan ABI.
Namun, jika kami tambahkan
new_field
setelahold_field
:kemudian perakitan lama yang dihasilkan masih mengakses yang pertama
int
dari struct, dan program masih bekerja, karena kami menjaga ABI stabil.Ini adalah versi yang sepenuhnya otomatis dari contoh ini di GitHub .
Cara lain untuk menjaga ABI ini stabil adalah memperlakukannya
mylib_mystruct
sebagai struct buram , dan hanya mengakses ladangnya melalui metode helpers. Ini membuatnya lebih mudah untuk menjaga ABI stabil, tetapi akan menimbulkan overhead kinerja karena kami akan melakukan lebih banyak panggilan fungsi.API vs ABI
Dalam contoh sebelumnya, menarik untuk dicatat bahwa menambahkan
new_field
sebelumnyaold_field
, hanya merusak ABI, tetapi bukan API.Apa artinya ini, adalah bahwa jika kita telah mengkompilasi ulang
main.c
program kita melawan perpustakaan, itu akan berhasil.Namun kami juga telah merusak API jika kami mengubah misalnya tanda tangan fungsi:
karena dalam kasus itu,
main.c
akan berhenti kompilasi sama sekali.Semantic API vs programming API vs ABI
Kami juga dapat mengklasifikasikan perubahan API dalam tipe ketiga: perubahan semantik.
Sebagai contoh, jika kita telah memodifikasi
untuk:
maka ini tidak akan merusak baik API maupun ABI, tetapi
main.c
akan tetap rusak!Ini karena kami mengubah "deskripsi manusia" dari apa fungsi yang seharusnya dilakukan daripada aspek yang terlihat secara program.
Saya hanya memiliki wawasan filosofis bahwa verifikasi formal perangkat lunak dalam arti memindahkan lebih dari "API semantik" ke lebih "API yang dapat diverifikasi secara terprogram".
API Semantik vs API Pemrograman
Kami juga dapat mengklasifikasikan perubahan API dalam tipe ketiga: perubahan semantik.
API semantik, biasanya merupakan deskripsi bahasa alami dari apa yang seharusnya dilakukan oleh API, biasanya termasuk dalam dokumentasi API.
Karena itu dimungkinkan untuk memecah API semantik tanpa merusak program itu sendiri.
Sebagai contoh, jika kita telah memodifikasi
untuk:
maka ini tidak akan merusak pemrograman API, maupun ABI, tetapi
main.c
API semantik akan rusak.Ada dua cara untuk memeriksa API kontrak secara terprogram:
Diuji di Ubuntu 18.10, GCC 8.2.0.
sumber
( A plikasi B inary I nterface) Sebuah spesifikasi untuk platform perangkat keras tertentu dikombinasikan dengan sistem operasi. Ini adalah satu langkah di luar API ( A pterication P rogram I nterface), yang mendefinisikan panggilan dari aplikasi ke sistem operasi. ABI mendefinisikan API plus bahasa mesin untuk keluarga CPU tertentu. API tidak memastikan kompatibilitas runtime, tetapi ABI melakukannya, karena ia menentukan bahasa mesin, atau format runtime.
Kesopanan
sumber
Izinkan saya memberikan contoh spesifik bagaimana ABI dan API berbeda di Jawa.
Perubahan ABI yang tidak kompatibel adalah jika saya mengubah metode A # m () dari mengambil
String
argumen sebagaiString...
argumen. Ini tidak kompatibel dengan ABI karena Anda harus mengkompilasi ulang kode yang memanggilnya, tetapi ini kompatibel dengan API karena Anda dapat menyelesaikannya dengan mengkompilasi ulang tanpa perubahan kode pada pemanggil.Berikut adalah contohnya. Saya memiliki perpustakaan Java saya dengan kelas A
Dan saya memiliki kelas yang menggunakan perpustakaan ini
Sekarang, penulis perpustakaan mengkompilasi kelas A mereka, saya mengkompilasi Main class saya dan semuanya bekerja dengan baik. Bayangkan versi baru A datang
Jika saya hanya mengambil kelas A yang baru dikompilasi dan menjatuhkannya bersama-sama dengan kelas Main yang sebelumnya telah dikompilasi, saya mendapatkan pengecualian pada upaya untuk memanggil metode
Jika saya mengkompilasi ulang Main, ini sudah diperbaiki dan semua bekerja kembali.
sumber
Program Anda (kode sumber) dapat dikompilasi dengan modul yang menyediakan API yang tepat .
Program Anda (biner) dapat berjalan pada platform yang menyediakan ABI yang tepat .
API membatasi jenis definisi, definisi fungsi, makro, terkadang variabel global yang harus dipaparkan oleh perpustakaan.
ABI membatasi apa "platform" harus menyediakan untuk menjalankan program Anda. Saya suka mempertimbangkannya dalam 3 level:
tingkat prosesor - set instruksi, konvensi pemanggilan
tingkat kernel - konvensi pemanggilan sistem, konvensi jalur file khusus (mis.
/proc
dan/sys
file di Linux), dll.Level OS - format objek, pustaka runtime, dll.
Pertimbangkan cross-compiler bernama
arm-linux-gnueabi-gcc
. "arm" menunjukkan arsitektur prosesor, "linux" menunjukkan kernel, "gnu" menunjukkan program targetnya menggunakan libc GNU sebagai pustaka runtime, berbeda denganarm-linux-androideabi-gcc
yang menggunakan implementasi libc Android.sumber
API
-Application Programming Interface
adalah antarmuka waktu kompilasi yang dapat digunakan oleh pengembang untuk menggunakan fungsionalitas non-proyek seperti perpustakaan, OS, panggilan inti dalam kode sumberABI
[Tentang] -Application Binary Interface
adalahantarmuka runtime yang digunakan oleh suatu program selama mengeksekusi untuk komunikasi antara komponen dalam kode mesinsumber