Eu sou novo na programação de sistemas linux e me deparei com API e ABI enquanto lia a programação de sistemas Linux .
Definição da API:
Uma API define as interfaces pelas quais um software se comunica com outro no nível de origem.
Definição de ABI:
Enquanto uma API define uma interface de origem, uma ABI define a interface binária de baixo nível entre duas ou mais partes de software em uma arquitetura específica. Ele define como um aplicativo interage consigo mesmo, como um aplicativo interage com o kernel e como um aplicativo interage com as bibliotecas.
Como um programa pode se comunicar no nível da fonte? O que é um nível de fonte? Está relacionado ao código fonte de qualquer maneira? Ou a fonte da biblioteca é incluída no programa principal?
A única diferença que eu sei é que a API é usada principalmente por programadores e a ABI é usada principalmente pelo compilador.
Respostas:
A API é o que os humanos usam. Nós escrevemos código fonte. Quando escrevemos um programa e queremos usar alguma função da biblioteca, escrevemos códigos como:
e precisávamos saber que existe um método
livenMyHills()
, que requer um parâmetro inteiro longo. Portanto, como uma interface de programação, tudo é expresso no código fonte. O compilador transforma isso em instruções executáveis que estão de acordo com a implementação desse idioma neste sistema operacional específico. E, nesse caso, resultam em algumas operações de baixo nível em uma unidade de áudio. Bits e bytes específicos são esguichos em algum hardware. Portanto, em tempo de execução, há muitas ações no nível binário em andamento que geralmente não vemos.fonte
API: interface do programa de aplicativos
Este é o conjunto de tipos / variáveis / funções públicas que você expõe do seu aplicativo / biblioteca.
Em C / C ++, é isso que você expõe nos arquivos de cabeçalho que você envia com o aplicativo.
ABI: Interface Binária do Aplicativo
É assim que o compilador cria um aplicativo.
Ele define as coisas (mas não se limita a):
fonte
Eu geralmente encontro esses termos no sentido de uma alteração incompatível com a API ou uma alteração incompatível com a ABI.
Uma mudança na API é essencialmente onde o código que seria compilado com a versão anterior não funcionará mais. Isso pode acontecer porque você adicionou um argumento a uma função ou alterou o nome de algo acessível fora do seu código local. Sempre que você altera um cabeçalho e obriga a alterar algo em um arquivo .c / .cpp, você faz uma alteração na API.
Uma alteração ABI é onde o código que já foi compilado na versão 1 não funcionará mais com a versão 2 de uma base de código (geralmente uma biblioteca). Geralmente, é mais complicado acompanhar as alterações incompatíveis com a API, pois algo tão simples como adicionar um método virtual a uma classe pode ser incompatível com ABI.
Encontrei dois recursos extremamente úteis para descobrir o que é a compatibilidade ABI e como preservá-la:
fonte
Estas são as minhas explicações para os leigos:
include
arquivos. Eles fornecem interfaces de programação.fonte
Exemplo de API mínima executável da biblioteca compartilhada Linux vs ABI
Esta resposta foi extraída da minha outra resposta: O que é uma interface binária de aplicativo (ABI)? mas senti que ele responde diretamente a este também, e que as perguntas não são duplicadas.
No contexto de bibliotecas compartilhadas, a implicação mais importante de "ter uma ABI estável" é que você não precisa recompilar seus programas após a alteração da biblioteca.
Como veremos no exemplo abaixo, é possível modificar a ABI, interrompendo os programas, mesmo que a API não seja alterada.
main.c
mylib.c
mylib.h
Compila e executa bem com:
Agora, suponha que, para a v2 da biblioteca, desejemos adicionar um novo campo ao
mylib_mystrict
chamadonew_field
.Se adicionamos o campo antes
old_field
como em:e reconstruiu a biblioteca, mas não
main.out
, a declaração falha!Isso ocorre porque a linha:
gerou um assembly que está tentando acessar o primeiro
int
da estrutura, que agora está emnew_field
vez do esperadoold_field
.Portanto, essa mudança quebrou a ABI.
Se, no entanto, adicionarmos
new_field
depoisold_field
:então, o antigo assembly gerado ainda acessa o primeiro
int
da estrutura e o programa ainda funciona, porque mantivemos a ABI estável.Aqui está um versão totalmente automatizada deste exemplo no GitHub .
Outra maneira de manter essa ABI estável seria tratar
mylib_mystruct
como uma estrutura opaca e acessar apenas seus campos por meio de auxiliares de método. Isso facilita a manutenção da ABI estável, mas acarretaria uma sobrecarga de desempenho, pois faríamos mais chamadas de função.API vs ABI
No exemplo anterior, é interessante notar que adicionar o
new_field
antesold_field
quebrou apenas a ABI, mas não a API.O que isso significa é que, se tivéssemos recompilado nosso
main.c
programa contra a biblioteca, ele teria funcionado independentemente.No entanto, também teríamos quebrado a API, se tivéssemos alterado, por exemplo, a assinatura da função:
pois nesse caso,
main.c
pararia de compilar completamente.API semântica vs API de programação vs ABI
Também podemos classificar as alterações da API em um terceiro tipo: alterações semânticas.
Por exemplo, se tivéssemos modificado
para:
então isso não
main.c
quebraria a API nem a ABI, mas ainda quebraria!Isso ocorre porque alteramos a "descrição humana" do que a função deve fazer, em vez de um aspecto perceptível programaticamente.
Acabei de ter a visão filosófica de que a verificação formal de software , de certo modo, move mais a "API semântica" para uma "API programaticamente verificável".
API semântica vs API de programação
Também podemos classificar as alterações da API em um terceiro tipo: alterações semânticas.
A API semântica, geralmente é uma descrição da linguagem natural do que a API deve fazer, geralmente incluída na documentação da API.
Portanto, é possível quebrar a API semântica sem interromper a construção do programa.
Por exemplo, se tivéssemos modificado
para:
então isso não
main.c
quebraria nem a API de programação nem a ABI, mas a API semântica seria interrompida.Há duas maneiras de verificar programaticamente a API do contrato:
Testado no Ubuntu 18.10, GCC 8.2.0.
fonte
( A APLICAÇÃO B inary eu nterface) Uma especificação de uma plataforma de hardware específico combinado com o sistema operativo. É um passo para além do API ( A APLICAÇÃO P rogram eu nterface), que define as chamadas a partir da aplicação para o sistema operativo. A ABI define a API mais a linguagem da máquina para uma família de CPU específica. Uma API não garante compatibilidade com o tempo de execução, mas uma ABI, porque define o formato da linguagem da máquina ou do tempo de execução.
Cortesia
fonte
Deixe-me dar um exemplo específico de como a ABI e a API diferem em Java.
Uma alteração incompatível com a ABI é se eu mudar um método A # m () de tomar a
String
como argumento paraString...
argumento. Isso não é compatível com ABI porque você precisa recompilar o código que está chamando isso, mas é compatível com a API, pois você pode resolvê-lo recompilando sem nenhuma alteração de código no chamador.Aqui está o exemplo explicitado. Eu tenho minha biblioteca Java com classe A
E eu tenho uma classe que usa esta biblioteca
Agora, o autor da biblioteca compilou sua classe A, compilei minha classe Main e está tudo funcionando bem. Imagine uma nova versão de A
Se eu apenas pegar a nova classe compilada A e soltá-la junto com a classe compilada anteriormente Main, eu recebo uma exceção na tentativa de chamar o método
Se eu recompilar Main, isso está corrigido e tudo está funcionando novamente.
fonte
Seu programa (código fonte) pode ser compilado com módulos que fornecem API adequada .
Seu programa (binário) pode ser executado em plataformas que fornecem ABI adequadas .
A API restringe definições de tipos, definições de funções, macros, às vezes variáveis globais que uma biblioteca deve expor.
A ABI restringe o que uma "plataforma" deve fornecer para que seu programa seja executado. Eu gosto de considerá-lo em 3 níveis:
nível do processador - o conjunto de instruções, a convenção de chamada
nível do kernel - a convenção de chamada do sistema, a convenção especial do caminho do arquivo (por exemplo, os arquivos
/proc
e/sys
no Linux), etc.Nível do SO - o formato do objeto, as bibliotecas de tempo de execução, etc.
Considere um compilador cruzado chamado
arm-linux-gnueabi-gcc
. "arm" indica a arquitetura do processador, "linux" indica o kernel, "gnu" indica que seus programas de destino usam a libc do GNU como biblioteca de tempo de execução, diferente daarm-linux-androideabi-gcc
implementação da libc do Android.fonte
API
-Application Programming Interface
é uma interface de tempo de compilação que pode ser usada pelo desenvolvedor para usar funcionalidades que não são do projeto, como biblioteca, SO, chamadas principais no código-fonteABI
[About] -Application Binary Interface
é umainterface de tempo de execução usada por um programa durante a execução da comunicação entre componentes no código da máquinafonte