PyBindGen
PyBindGen is a code generator that produces C++ source files to create Python bindings for C/C++ libraries. It helps expose C/C++ functions and classes to Python without writing manual wrapper code. As of version 0.22.1, it's an active project with a slow but steady release cadence, often tied to changes in `ns-3` (its primary consumer).
Common errors
-
fatal error: Python.h: No such file or directory
cause During compilation of the generated C++ binding code, the C++ compiler cannot find the Python development header files, which are essential for building Python extension modules.fixInstall the Python development package for your system. For Debian/Ubuntu: `sudo apt-get install python3-dev`. For Fedora/RHEL: `sudo dnf install python3-devel`. For macOS with Xcode Command Line Tools, Python headers are usually available, but ensure `python3` is linked correctly. -
undefined reference to `MyCppNamespace::add(int, int)`
cause This linker error occurs during the compilation of the generated C++ binding code. It means the linker cannot find the actual C++ function `add` (or any other function/class) that the bindings are supposed to wrap. This usually happens because the library containing the actual C++ code was not linked.fixEnsure that the C++ library containing `MyCppNamespace::add` (or your actual C++ code) is correctly linked against the generated binding code. If using `setuptools.Extension`, add `libraries=['mylibrary']` and `library_dirs=['/path/to/lib']` to your `Extension` definition. -
ImportError: dynamic module does not define module export function (PyInit_my_bindings_module)
cause This runtime error typically occurs when trying to `import` the compiled Python extension module. It indicates an issue with the compiled shared library, often due to an incorrect build configuration (e.g., wrong Python ABI, incorrect entry point generation, or an old Python version being used).fixVerify that the generated C++ code was compiled against the correct Python version and ABI. Ensure PyBindGen's `Module` constructor's `py_init_name` (if explicitly set) matches the `PyInit_` function expected by your Python interpreter. Rebuild the module cleanly, ensuring all dependencies are met for the target Python environment.
Warnings
- gotcha PyBindGen only generates C++ binding code; it does not compile it. Users must have a C++ compiler (e.g., g++ or clang) and Python development headers installed to compile the generated `.cc` files into a Python extension module.
- gotcha The generated C++ code needs to be integrated into a build system (e.g., `setuptools`, `waf`, `CMake`) to be compiled and linked correctly as a Python extension module. Simply generating the `.cc` file is only the first step.
- gotcha Wrapping complex C++ features like templates, custom memory management, or deep inheritance hierarchies can be challenging and may require manual adjustments or advanced PyBindGen techniques not covered in simple examples.
Install
-
pip install pybindgen
Imports
- Module
from pybindgen import Module
- Parameter
from pybindgen import Parameter
- ReturnValue
from pybindgen import ReturnValue
Quickstart
from pybindgen import Module, Function, Parameter, ReturnValue
def generate_bindings(filename):
module = Module('my_bindings_module', cpp_namespace='MyCppNamespace')
# Example: Bind a simple C++ function 'int add(int a, int b);'
module.add_function(
'add',
retval=ReturnValue.copy(Parameter.new('int', 'a')),
params=[Parameter.new('int', 'a'), Parameter.new('int', 'b')]
)
# Generate the C++ binding code
module.generate(filename)
print(f"Generated binding code to {filename}")
# To run this, you would typically integrate it into a setup.py or build script
# For a standalone example:
# generate_bindings('my_bindings_module.cc')