Skip to content
Latchkey

What Is an ABI? The Binary Contract Between Programs

An ABI (Application Binary Interface) is the low-level contract that lets compiled code interoperate: how functions are called, how data is laid out, and how the binary fits together.

An API defines how source code interfaces at the language level. An ABI is the same idea one layer down, at the level of machine code. It specifies the binary details two compiled components must agree on to work together: calling conventions, how arguments are passed, how structures are laid out in memory, and how symbols are named. Break the ABI and binaries that compiled fine fail at runtime.

What an ABI specifies

  • Calling conventions: how arguments and return values are passed.
  • Data layout: sizes, alignment, and ordering of structures.
  • Name mangling: how symbol names are encoded in object files.
  • The binary format and how the program is loaded.

ABI vs API

An API is a source-level contract: which functions and types exist and how to call them in code. An ABI is a binary-level contract: how that compiled code actually interoperates. You can keep an API stable while breaking the ABI, and vice versa.

Why ABI stability matters

Dynamic linking relies on ABI stability. A shared library can be updated without recompiling its callers only if the new version keeps the same ABI. Change the layout of a struct or a calling convention, and existing binaries break in confusing, hard-to-debug ways.

When ABIs break

ABI breaks cause crashes or corruption that are baffling because nothing in the source looks wrong, the mismatch is purely binary. This is why mixing components built with different compilers, flags, or library versions can fail unpredictably.

A quick example

Updating a shared library so a struct gains a field changes its memory layout. Programs compiled against the old layout still expect the old size and read the wrong bytes, despite source that compiles fine.

ABI in CI

ABI mismatches are environment problems: the same code fails when binaries are built against incompatible toolchains or library versions. Latchkey provides consistent, reproducible runner environments so components are built and linked against compatible ABIs, avoiding mysterious works-on-my-machine binary failures.

Key takeaways

  • An ABI is the binary-level contract that lets compiled code interoperate.
  • It is distinct from an API: ABI is about machine code, API is about source.
  • ABI breaks cause baffling runtime failures even when the source compiles cleanly.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →