Difference between API and ABI



Answers

API: Application Program Interface

This is the set of public types/variables/functions that you expose from your application/library.

In C/C++ this is what you expose in the header files that you ship with the application.

ABI: Application Binary Interface

This is how the compiler builds an application.
It defines things (but is not limited to):

  • How parameters are passed to functions (registers/stack).
  • Who cleans parameters from the stack (caller/callee).
  • Where the return value is placed for return.
  • How exceptions propagate.
Question

I am new to linux system programming and I came across API and ABI while reading Linux System Programming.

Definition of API :

An API defines the interfaces by which one piece of software communicates with another at the source level.

Definition of ABI :

Whereas an API defines a source interface, an ABI defines the low-level binary interface between two or more pieces of software on a particular architecture. It defines how an application interacts with itself, how an application interacts with the kernel, and how an application interacts with libraries.

How can a program communicate at a source level ? What is a source level ? Is it related to source code in anyway? Or the source of the library gets included in the main program ?

The only difference I know is API is mostly used by programmers and ABI is mostly used by compiler.




this is my layman explanations:

  • api - think include files. they provide programming interface
  • abi - think kernel module. when you run it on some kernel, they has to agree how to communicate without include files, ie as low-level binary interface



Let me give a specific example how ABI and API differ in Java.

An ABI incompatible change is if I change a method A#m() from taking a String as an argument to String... argument. This is not ABI compatible because you have to recompile code that is calling that, but it is API compatible as you can resolve it by recompiling without any code changes in the caller.

Here is the example spelled out. I have my Java library with class A

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

And I have a class that uses this library

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

Now, the library author compiled their class A, I compiled my class Main and it is all working nicely. Imagine a new version of A comes

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

If I just take the new compiled class A and drop it together with the previously compiled class Main, I get an exception on attempt to invoke the method

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

If I recompile Main, this is fixed and all is working again.




Links