ctypesgen
ctypesgen is a Python wrapper generator for `ctypes`, designed to automate the creation of Python bindings for C header files. It parses C/C++ header files and generates Python modules that use the `ctypes` foreign function interface to call functions and access data structures in shared C libraries. The current version is 1.1.1, with releases occurring periodically to address bugs and introduce new features, often yearly or bi-annually.
Common errors
-
ModuleNotFoundError: No module named 'ply'
cause The `ply` package is a mandatory dependency for `ctypesgen` to parse C header files, but it was not installed.fixInstall `ctypesgen` correctly using `pip install ctypesgen` or manually `pip install ply`. -
FileNotFoundError: [Errno 2] No such file or directory: 'gcc'
cause ctypesgen uses an external C compiler (like `gcc` or `clang`) to preprocess and parse C header files. This error indicates that the compiler is not found in the system's PATH.fixInstall a C/C++ compiler (e.g., `build-essential` on Debian/Ubuntu, Xcode Command Line Tools on macOS, or MinGW/MSVC on Windows) and ensure it's added to your system's PATH. -
TypeError: main() takes 1 positional argument but 2 were given
cause When calling `ctypesgen.main.main()`, command-line arguments are expected as a single list of strings, not separate arguments.fixPass all arguments as a single list: `ctypesgen.main.main(['-o', 'output.py', 'input.h'])`.
Warnings
- breaking Python 2 support was completely dropped in version 1.1.0. Older projects relying on ctypesgen with Python 2 must remain on a pre-1.1.0 version or migrate to Python 3.
- gotcha `ctypesgen` relies on an underlying C compiler (like `gcc` or `clang`) being present in your system's PATH to parse C header files. If not found, it will fail to process headers.
- gotcha When using `ctypesgen.main.main()` programmatically, arguments must be passed as a single list of strings, mimicking `sys.argv[1:]`. Passing them as separate arguments will result in a `TypeError`.
- gotcha By default, `ctypesgen` embeds a preamble (library loader code) in each generated output file. For packaging or reducing duplication, use `--no-embed-preamble` to generate the preamble and loader into separate files.
Install
-
pip install ctypesgen
Imports
- main
import ctypesgen
import ctypesgen.main
Quickstart
import os
import ctypesgen.main
# 1. Define your C header content
header_content = """
// my_library.h
#ifndef MY_LIBRARY_H
#define MY_LIBRARY_H
int add_numbers(int a, int b);
void print_message(const char* msg);
#endif
"""
# 2. Create a temporary header file
header_file = "my_library.h"
with open(header_file, "w") as f:
f.write(header_content)
# 3. Define the output Python bindings file
output_file = "my_library_bindings.py"
# 4. Run ctypesgen programmatically using its main function
# Arguments are passed as a list of strings, just like command-line arguments.
ctypesgen.main.main(["-o", output_file, header_file])
print(f"Successfully generated bindings to '{output_file}'")
print("To use them, compile 'my_library.h' into a shared library (e.g., .so, .dylib, .dll),\n"+
"then import 'my_library_bindings' in Python and load the shared library.")
# 5. Clean up temporary files
os.remove(header_file)