{"id":263,"library":"cffi","title":"CFFI — C Foreign Function Interface for Python","description":"CFFI (C Foreign Function Interface) lets Python code call C libraries by declaring C-like function signatures and types that can often be copy-pasted directly from header files. It supports four modes: ABI/API level each with inline or out-of-line (pre-compiled) preparation. The current stable release is 2.0.0 (released September 2025), requiring Python >=3.9. It is the recommended way to interface with C on PyPy and is used as a foundation by cryptography, bcrypt, and many other major Python packages.","status":"active","version":"2.0.0","language":"python","source_language":"en","source_url":"https://github.com/python-cffi/cffi","tags":["ffi","c-bindings","ctypes-alternative","native","extension","pypy","systems"],"install":[{"cmd":"pip install cffi","lang":"bash","label":"Install cffi"}],"dependencies":[{"reason":"Required to parse C declarations passed to ffi.cdef(); automatically pulled in by pip install cffi.","package":"pycparser","optional":false},{"reason":"Required 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.","package":"setuptools","optional":true}],"imports":[{"note":"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.","wrong":"import cffi; cffi.FFI()","symbol":"FFI","correct":"from cffi import FFI"},{"note":"In out-of-line API mode the compiled extension exports its own 'ffi' (CompiledFFI) and 'lib' objects; do not re-instantiate FFI() at runtime.","symbol":"FFI (out-of-line)","correct":"from _my_compiled_module import ffi, lib"}],"quickstart":{"code":"from cffi import FFI\n\nffi = FFI()\n\n# Declare the C function signature (copy-paste from man page / header)\nffi.cdef(\"\"\"\n    size_t strlen(const char *s);\n\"\"\")\n\n# ABI mode: open the C standard library\nC = ffi.dlopen(None)  # None = current process / libc on POSIX\n                      # On Windows use ffi.dlopen('msvcrt') instead\n\n# char* arguments must be bytes, not str\nresult = C.strlen(b\"hello, cffi\")\nprint(result)  # 11\n\n# Allocate a C buffer\nbuf = ffi.new(\"char[]\", b\"world\")\nprint(ffi.string(buf))  # b'world'\n","lang":"python","description":"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."},"warnings":[{"fix":"If interfacing with a library that stores non-0/1 values in bool fields, replace 'bool' with 'uint8_t' in your ffi.cdef() declaration.","message":"In 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.","severity":"breaking","affected_versions":"<2.0.0 → 2.0.0"},{"fix":"Upgrade to Python 3.9+. If you must target older Pythons, pin cffi<2.","message":"Python 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).","severity":"breaking","affected_versions":"<2.0.0"},{"fix":"Iterate the bool[] directly or cast to uint8_t[] before calling ffi.string().","message":"ffi.string() no longer works on bool[] arrays. It previously returned raw bytes up to the first zero byte, which was rarely meaningful.","severity":"breaking","affected_versions":"<2.0.0 → 2.0.0"},{"fix":"Use b'...' literals or call str.encode() before passing strings to CFFI char* parameters. Decode return values with ffi.string(ptr).decode().","message":"char* 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').","severity":"gotcha","affected_versions":"all"},{"fix":"Use out-of-line API mode (ffibuilder.set_source + ffibuilder.compile) for production bindings. Reserve ABI/inline mode for quick experiments only.","message":"ABI 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.","severity":"gotcha","affected_versions":"all"},{"fix":"Add 'setuptools' to your package's build-system requires and/or install_requires when using CFFI's build integration.","message":"On 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.","severity":"gotcha","affected_versions":">=1.16.0 on Python 3.12+"},{"fix":"On Windows, use ffi.dlopen('msvcrt') or specify the full path to the target DLL instead of passing None.","message":"ffi.dlopen(None) does not work on Python 3 on Windows. It raises OSError or returns an unusable handle.","severity":"gotcha","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-12T12:28:48.128Z","next_check":"2026-06-26T00:00:00.000Z","problems":[{"fix":"Activate 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.","cause":"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.","error":"No module named '_cffi_backend'"},{"fix":"Ensure 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.","cause":"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.","error":"OSError: cannot load library 'your_library_name.dll': error 0x7e"},{"fix":"Carefully 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.","cause":"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).","error":"ImportError: ... undefined symbol: some_function_name"},{"fix":"To 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.","cause":"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`).","error":"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."}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":80,"quickstart_tag":"verified","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"19.2M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0.3,"disk_size":"20M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.4,"disk_size":"21.3M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.4,"disk_size":"22M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"13.2M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"14M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.6,"disk_size":"12.8M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"13M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.3,"disk_size":"19.4M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0.3,"disk_size":"20M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"verified","tag_description":"quickstart runs on critical runtimes, recently tested","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}