Install & Compatibility
Where this runs
tested against v2.1.1 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.006s · 19.2MB
glibcpy 3.10–3.95 runs
installs and imports cleanly · install 2.0s · import 0.006s · 20MB
18MB installed
● package 18MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
FFI
✓ from cffi import FFI
✗ import cffi; cffi.FFI()
Both forms work, but 'from cffi import FFI' is the canonical pattern used throughout the official docs. Using cffi.FFI() directly after a bare import is verbose but not broken.
FFI (out-of-line)
✓ from _my_compiled_module import ffi, lib
In out-of-line API mode the compiled extension exports its own 'ffi' (CompiledFFI) and 'lib' objects; do not re-instantiate FFI() at runtime.
Inline ABI mode: declare a C function signature and call it via dlopen. No C compiler needed, but prefer out-of-line API mode for production.
from cffi import FFI
ffi = FFI()
# Declare the C function signature (copy-paste from man page / header)
ffi.cdef("""
size_t strlen(const char *s);
""")
# ABI mode: open the C standard library
C = ffi.dlopen(None) # None = current process / libc on POSIX
# On Windows use ffi.dlopen('msvcrt') instead
# char* arguments must be bytes, not str
result = C.strlen(b"hello, cffi")
print(result) # 11
# Allocate a C buffer
buf = ffi.new("char[]", b"world")
print(ffi.string(buf)) # b'world'
Debug
Known issues
breakingIn 2.0.0, reading a C '_Bool'/'bool' field whose underlying byte is not exactly 0 or 1 now raises an exception instead of returning the raw integer. Previously undefined-behavior values were silently returned.fixIf interfacing with a library that stores non-0/1 values in bool fields, replace 'bool' with 'uint8_t' in your ffi.cdef() declaration.
affects: <2.0.0 → 2.0.0
breakingPython 2.7, 3.6, and 3.7 support was dropped. The minimum supported version is now Python 3.9 (as of 2.0.0 PyPI metadata).fixUpgrade to Python 3.9+. If you must target older Pythons, pin cffi<2.
affects: <2.0.0
breakingffi.string() no longer works on bool[] arrays. It previously returned raw bytes up to the first zero byte, which was rarely meaningful.fixIterate the bool[] directly or cast to uint8_t[] before calling ffi.string().
affects: <2.0.0 → 2.0.0
gotchachar* in C corresponds to bytes in Python 3, not str. Passing a Python str to any char* argument raises TypeError or produces garbage. Always encode strings explicitly: s.encode('utf-8').fixUse b'...' literals or call str.encode() before passing strings to CFFI char* parameters. Decode return values with ffi.string(ptr).decode().
affects: all
gotchaABI mode (ffi.dlopen) is error-prone: wrong type declarations cause silent data corruption or crashes rather than compile-time errors. API mode (ffi.set_source + ffi.compile) is verified by a real C compiler.fixUse out-of-line API mode (ffibuilder.set_source + ffibuilder.compile) for production bindings. Reserve ABI/inline mode for quick experiments only.
affects: all
gotchaOn Python 3.12+ any code path that calls ffi.compile() or uses cffi_modules= in setup.py requires setuptools at runtime because distutils was removed. CFFI does not declare this dependency automatically.fixAdd 'setuptools' to your package's build-system requires and/or install_requires when using CFFI's build integration.
affects: >=1.16.0 on Python 3.12+
gotchaffi.dlopen(None) does not work on Python 3 on Windows. It raises OSError or returns an unusable handle.fixOn Windows, use ffi.dlopen('msvcrt') or specify the full path to the target DLL instead of passing None. affects: all
Errors
Common errors & fixes
No module named '_cffi_backend'
The `_cffi_backend` C extension module, which is a core part of `cffi`, is either not installed, corrupted, or cannot be found by the Python interpreter. This often happens due to issues with virtual environments, multiple Python installations, or build failures during installation.
fixActivate your virtual environment (if any), then run `pip uninstall cffi && pip install cffi`. Ensure you have the necessary system build tools (e.g., C compiler, `python3-dev`, `libffi-dev` on Linux, Visual C++ build tools on Windows) installed before reinstalling.
OSError: cannot load library 'your_library_name.dll': error 0x7e
The C shared library (e.g., DLL on Windows, .so on Linux, .dylib on macOS) that `ffi.dlopen()` is attempting to load cannot be found by the operating system, or the library itself has missing dependencies. On Windows, `error 0x7e` specifically indicates that the specified module could not be found, often implying a missing dependent DLL.
fixEnsure the C library file (`your_library_name.dll`, `.so`, or `.dylib`) exists and is located in a directory included in your system's library search path (e.g., `PATH` on Windows, `LD_LIBRARY_PATH` on Linux, `DYLD_LIBRARY_PATH` on macOS). Alternatively, provide an absolute path to the library in `ffi.dlopen()`. Verify that all dynamic dependencies of `your_library_name` are also present and discoverable.
ImportError: ... undefined symbol: some_function_name
The C function or global variable declared in `ffi.cdef()` is not exported by the loaded C shared library, or there is an ABI (Application Binary Interface) incompatibility between the C library and the Python environment (e.g., C++ name mangling, different compiler versions used for `cffi` and the target C library, or Python C API changes).
fixCarefully compare the C function/symbol name and signature in `ffi.cdef()` with the actual C header and exported symbols (e.g., using `nm` on Linux). If the C library is written in C++, ensure the functions are declared `extern "C"` to prevent name mangling. Confirm that the C library was compiled with a compatible compiler and settings for your environment and Python version.
Exception: Version mismatch: this is the 'cffi' package version X.Y.Z, located in '.../cffi/api.py'. When we import the top-level '_cffi_backend' extension module, we get version A.B.C.
There is a mismatch between the installed Python `cffi` package (the Python-level code) and its underlying compiled C extension module (`_cffi_backend`). This usually means different versions of these components are being loaded, often due to incomplete upgrades, multiple `cffi` installations, or mixing `pip` installations with system package manager installations (e.g., `apt`).
fixTo resolve this, completely uninstall and then reinstall `cffi` to ensure all its components are synchronized: `pip uninstall cffi && pip install cffi`. If you manage Python packages via a system package manager, ensure that both `cffi` and its backend are from the same source, or prefer using a virtual environment and `pip` exclusively for `cffi` related packages.
Upgrade
Version history
2.1.1latest on PyPI · released Aug 3, 2026
Audit
Dependencies
pycparserrequiredRequired to parse C declarations passed to ffi.cdef(); automatically pulled in by pip install cffi.
setuptoolsoptionalRequired at runtime when using CFFI's distutils/setuptools integration (ffi.compile(), cffi_modules=) on Python 3.12+ where distutils was removed from the stdlib. CFFI does not declare this automatically.