C++-Python-Interface-Wrapping
Summary
Convert a compiled C++ library into importable Python modules using binding generators (e.g. nanobind, SWIG) so that Python code can call C++ functions and classes directly. This skill is essential when you need to expose computationally intensive or legacy C++ code to Python workflows without rewriting the core logic.
When to use
Apply this skill when you have a mature C++ library (like OpenMS) with stable APIs that you want to make accessible from Python environments, and you need to preserve performance-critical C++ execution while supporting rapid prototyping or integration into Python-based data pipelines (e.g., KNIME, Jupyter, or workflow engines).
When NOT to use
- The C++ library is still under active development with unstable or frequently changing APIs—interface wrapping is brittle to C++ signature changes.
- Performance requirements can be met entirely in pure Python or via existing wheel packages—wrapping adds build complexity without proportional benefit.
- The C++ code is tightly coupled to platform-specific features or low-level system APIs that are difficult to expose safely through a language boundary.
Inputs
- C++ header files (.h, .hpp) defining classes and functions to expose
- Binding specification files (nanobind .pyi or SWIG .i files)
- CMakeLists.txt or build configuration linking C++ sources and binding files
- Compiled C++ library or object files (.a, .lib, .so)
Outputs
- Compiled Python extension module (.so on Linux, .pyd on Windows, .dylib on macOS)
- Importable Python module (e.g.,
import pyOpenMS)
- Python package with C++ class and function bindings accessible via Python syntax
How to apply
Identify the C++ headers and classes to expose in the binding specification files (e.g., nanobind .pyi definitions in src/pyOpenMS/bindings/). Configure the build system (CMake) to invoke the binding generator on these specifications, compiling the resulting bindings into a Python extension module (.so on Linux, .pyd on Windows). Execute the build to generate the compiled module. Import the module in a Python environment using standard import syntax. Verify successful wrapping by calling a simple C++ function or accessing a class attribute through the Python interface, confirming that the binding preserves the expected method signatures and return types.
Related tools
- nanobind (Binding generator that converts C++ classes and functions into importable Python modules with minimal boilerplate)
- CMake (Build system that orchestrates compilation of C++ sources, invokes the binding generator, and links the resulting extension module) — https://github.com/OpenMS/OpenMS
- OpenMS C++ library (Source C++ codebase (mass spectrometry algorithms and data structures) to be wrapped) — https://github.com/OpenMS/OpenMS
Evaluation signals
- The compiled extension module exists in the expected output directory and has the correct platform-specific file extension (.so, .pyd, .dylib).
- The module can be imported without C++ linker or runtime errors:
import pyOpenMS succeeds.
- A simple C++ function or class method is callable from Python and returns data with the correct type and structure (e.g.,
pyOpenMS.MSExperiment() instantiates a Python object wrapping the C++ class).
- Signature inspection in Python matches the C++ API:
help(pyOpenMS.MSExperiment) or dir(pyOpenMS) lists expected methods and attributes.
- Round-trip data conversion works: passing Python data structures to C++ functions and receiving results back preserves semantics (e.g., numeric precision, list ordering, object identity).
Limitations
- Binding specification files must be maintained in sync with C++ API changes; breaking C++ API changes require updates to binding files and rebuild.
- Complex C++ features (template metaprogramming, operator overloading edge cases, multiple inheritance) may require explicit binding code or workarounds in the binding generator configuration.
- Performance of bound code depends on copy/move semantics across the C++–Python boundary; frequent small data transfers can negate the speed advantage of C++ execution.
- The generated Python module is binary-platform-specific; wheels must be built separately for each OS and Python version combination.
- Debugging stack traces may be difficult to interpret when errors originate in C++ code beneath the binding layer.
Evidence
- [other] The provided document fragment does not contain sufficient technical description of the binding generation mechanism, binding file structure, or module import verification process to extract a bounded finding.: "The provided document fragment does not contain sufficient technical description of the binding generation mechanism"
- [other] Navigate to the src/pyOpenMS/bindings/ directory and review nanobind binding specifications according to CLAUDE.md wrapping instructions. Configure the build system (CMake) to compile nanobind binding files into a Python extension module. Execute the build process to generate the compiled pyOpenMS module. Import the generated pyOpenMS module in a Python environment and verify that the module loads without errors. Execute a simple function call or attribute access on the imported module to confirm binding completeness.: "Navigate to the src/pyOpenMS/bindings/ directory and review nanobind binding specifications... Import the generated pyOpenMS module in a Python environment and verify that the module loads without"
- [readme] With pyOpenMS, OpenMS offers Python bindings to a large part of the OpenMS API to enable rapid algorithm development.: "With pyOpenMS, OpenMS offers Python bindings to a large part of the OpenMS API to enable rapid algorithm development."
- [readme] It supports easy integration of OpenMS built tools into workflow engines like nextflow, KNIME, Galaxy, and TOPPAS via the TOPPTools concept: "It supports easy integration of OpenMS built tools into workflow engines like nextflow, KNIME, Galaxy, and TOPPAS"
- [readme] Documentation for the Python bindings pyOpenMS can be found on the pyOpenMS online documentation: "Documentation for the Python bindings pyOpenMS can be found on the pyOpenMS online documentation"
1---2name: c-python-interface-wrapping-23description: Use when you have a mature C++ library (like OpenMS) with stable APIs that you want to make accessible from Python environments, and you need to preserve performance-critical C++ execution while supporting rapid prototyping or integration into Python-based data pipelines (e.4license: CC-BY-4.05---67# C++-Python-Interface-Wrapping89## Summary1011Convert a compiled C++ library into importable Python modules using binding generators (e.g. nanobind, SWIG) so that Python code can call C++ functions and classes directly. This skill is essential when you need to expose computationally intensive or legacy C++ code to Python workflows without rewriting the core logic.1213## When to use1415Apply this skill when you have a mature C++ library (like OpenMS) with stable APIs that you want to make accessible from Python environments, and you need to preserve performance-critical C++ execution while supporting rapid prototyping or integration into Python-based data pipelines (e.g., KNIME, Jupyter, or workflow engines).1617## When NOT to use1819- The C++ library is still under active development with unstable or frequently changing APIs—interface wrapping is brittle to C++ signature changes.20- Performance requirements can be met entirely in pure Python or via existing wheel packages—wrapping adds build complexity without proportional benefit.21- The C++ code is tightly coupled to platform-specific features or low-level system APIs that are difficult to expose safely through a language boundary.2223## Inputs2425- C++ header files (.h, .hpp) defining classes and functions to expose26- Binding specification files (nanobind .pyi or SWIG .i files)27- CMakeLists.txt or build configuration linking C++ sources and binding files28- Compiled C++ library or object files (.a, .lib, .so)2930## Outputs3132- Compiled Python extension module (.so on Linux, .pyd on Windows, .dylib on macOS)33- Importable Python module (e.g., `import pyOpenMS`)34- Python package with C++ class and function bindings accessible via Python syntax3536## How to apply3738Identify the C++ headers and classes to expose in the binding specification files (e.g., nanobind .pyi definitions in src/pyOpenMS/bindings/). Configure the build system (CMake) to invoke the binding generator on these specifications, compiling the resulting bindings into a Python extension module (.so on Linux, .pyd on Windows). Execute the build to generate the compiled module. Import the module in a Python environment using standard import syntax. Verify successful wrapping by calling a simple C++ function or accessing a class attribute through the Python interface, confirming that the binding preserves the expected method signatures and return types.3940## Related tools4142- **nanobind** (Binding generator that converts C++ classes and functions into importable Python modules with minimal boilerplate)43- **CMake** (Build system that orchestrates compilation of C++ sources, invokes the binding generator, and links the resulting extension module) — https://github.com/OpenMS/OpenMS44- **OpenMS C++ library** (Source C++ codebase (mass spectrometry algorithms and data structures) to be wrapped) — https://github.com/OpenMS/OpenMS4546## Evaluation signals4748- The compiled extension module exists in the expected output directory and has the correct platform-specific file extension (.so, .pyd, .dylib).49- The module can be imported without C++ linker or runtime errors: `import pyOpenMS` succeeds.50- A simple C++ function or class method is callable from Python and returns data with the correct type and structure (e.g., `pyOpenMS.MSExperiment()` instantiates a Python object wrapping the C++ class).51- Signature inspection in Python matches the C++ API: `help(pyOpenMS.MSExperiment)` or `dir(pyOpenMS)` lists expected methods and attributes.52- Round-trip data conversion works: passing Python data structures to C++ functions and receiving results back preserves semantics (e.g., numeric precision, list ordering, object identity).5354## Limitations5556- Binding specification files must be maintained in sync with C++ API changes; breaking C++ API changes require updates to binding files and rebuild.57- Complex C++ features (template metaprogramming, operator overloading edge cases, multiple inheritance) may require explicit binding code or workarounds in the binding generator configuration.58- Performance of bound code depends on copy/move semantics across the C++–Python boundary; frequent small data transfers can negate the speed advantage of C++ execution.59- The generated Python module is binary-platform-specific; wheels must be built separately for each OS and Python version combination.60- Debugging stack traces may be difficult to interpret when errors originate in C++ code beneath the binding layer.6162## Evidence6364- [other] The provided document fragment does not contain sufficient technical description of the binding generation mechanism, binding file structure, or module import verification process to extract a bounded finding.: "The provided document fragment does not contain sufficient technical description of the binding generation mechanism"65- [other] Navigate to the src/pyOpenMS/bindings/ directory and review nanobind binding specifications according to CLAUDE.md wrapping instructions. Configure the build system (CMake) to compile nanobind binding files into a Python extension module. Execute the build process to generate the compiled pyOpenMS module. Import the generated pyOpenMS module in a Python environment and verify that the module loads without errors. Execute a simple function call or attribute access on the imported module to confirm binding completeness.: "Navigate to the src/pyOpenMS/bindings/ directory and review nanobind binding specifications... Import the generated pyOpenMS module in a Python environment and verify that the module loads without"66- [readme] With pyOpenMS, OpenMS offers Python bindings to a large part of the OpenMS API to enable rapid algorithm development.: "With pyOpenMS, OpenMS offers Python bindings to a large part of the OpenMS API to enable rapid algorithm development."67- [readme] It supports easy integration of OpenMS built tools into workflow engines like nextflow, KNIME, Galaxy, and TOPPAS via the TOPPTools concept: "It supports easy integration of OpenMS built tools into workflow engines like nextflow, KNIME, Galaxy, and TOPPAS"68- [readme] Documentation for the Python bindings pyOpenMS can be found on the pyOpenMS online documentation: "Documentation for the Python bindings pyOpenMS can be found on the pyOpenMS online documentation"