There are several ways to call code written in C from Python.

First, there is the ctypes module in the standard library. It allows you to load a dynamic-link library (DLL on Windows, shared libraries .so on Linux) and call functions from these libraries, directly from Python. Such libraries are usually written in C.

Second, in case of CPython there is the Python/C API. It can be used in two major ways:

A dynamic-link library can be written in C in such a way that CPython will treat it as a module (you will be able to import it in your Python programs). The Python/C API allows the library to define functions that are written in C but still callable from Python. The API is very powerful and provides functions to manipulate all Python data types and access the internals of the interpreter.

The second way to use the C API is to embed Python in a program written in C. The C program is then able to create built-in modules written in C and expose C functions, much like in the dynamic-link library approach. The API also allows the program to execute scripts which can then import and use the built-in modules. This can be used to create a Python based plug-in system.

"Bindings" are implemented either as a pure Python library using ctypes or as a dynamic-link library using Python/C API. The second option is sometimes used with tools like SWIG which make the task easier by taking care of generating the "boiler-plate" code or Boost.Python which provides a C++ API on top of Python/C API making it easier to interface with C++ code.

Further read: Foreign Function Interface

Answer from yak on Stack Overflow
🌐
Real Python
realpython.com › python-bindings-overview
Python Bindings: Calling C or C++ From Python – Real Python
March 18, 2026 - Are you a Python developer with a C or C++ library you’d like to use from Python? If so, then Python bindings allow you to call functions and pass data from Python to C or C++, letting you take advantage of the strengths of both languages.
Top answer
1 of 2
79

There are several ways to call code written in C from Python.

First, there is the ctypes module in the standard library. It allows you to load a dynamic-link library (DLL on Windows, shared libraries .so on Linux) and call functions from these libraries, directly from Python. Such libraries are usually written in C.

Second, in case of CPython there is the Python/C API. It can be used in two major ways:

A dynamic-link library can be written in C in such a way that CPython will treat it as a module (you will be able to import it in your Python programs). The Python/C API allows the library to define functions that are written in C but still callable from Python. The API is very powerful and provides functions to manipulate all Python data types and access the internals of the interpreter.

The second way to use the C API is to embed Python in a program written in C. The C program is then able to create built-in modules written in C and expose C functions, much like in the dynamic-link library approach. The API also allows the program to execute scripts which can then import and use the built-in modules. This can be used to create a Python based plug-in system.

"Bindings" are implemented either as a pure Python library using ctypes or as a dynamic-link library using Python/C API. The second option is sometimes used with tools like SWIG which make the task easier by taking care of generating the "boiler-plate" code or Boost.Python which provides a C++ API on top of Python/C API making it easier to interface with C++ code.

Further read: Foreign Function Interface

2 of 2
21

Answer is simple, python (CPython) interpreter is written in C and it can call other C libraries dynamically, your C extension module or embedded C code can be easily called from any other C code.

CPython allows special hooks so that it can call other C code or can be called from other C code. It need not even be C, any language which compiles to native code and have same calling convention.

For a simple case consider you create a program called mython, which can load any shared library and tries to call a function run e.g.

lib = dlopen("mylib.so", RTLD_LAZY);
func = dlsym(lib, "run");
(*func)();

So in way you have loaded a module and called its code, CPython does that but in more complex way, providing better interfaces and objects to pass around, plus there are other intricacies involved of memory management, thread management etc.

So platform of Python implementation must match to language in which it is being extended, e.g. CPython is not extensible in Java but Java implementation of Python called Jython can be extended in Java and similarly .NET implementation IronPython can be extended in .Net languages.

Discussions

interfacing python with c/c++ performance
I did that for an automated video testing system I built for Comcast. We needed C++ for speed but wanted the tests to be written in Python. So all the video processing and backend stuff was written in C++ (Using ffmpeg, OpenCV and Tesseract for OCR) and the video processing libraries had a Boost::Python API to interact with the system objects. I set all the C++ objects up with JSON serialization, so you could create a C++ object in Python using JSON and that might kick some threads off to run in the background while your slow-ass python program did shit in the foreground. Overall this worked very well but it took very careful planning to make sure it did. So for example, if you wanted to tell the system to watch for an image, the API call would queue the image up in a vector internally and notify the internal components to move any images in the vector to another location to avoid blocking things for too long. Then tasks would be dispatched to thread pools to check each video frame against a copy of that image. The system had plenty of memory and we were never looking for a huge number of images, so it made sense to do it that way. Generally we were pretty close to real-time performance as long as no one did anything stupid (Like try to watch for an entire video's worth of video frames in the stream.) Once the thread pool got saturated, C++-side performance would degrade. This approach had a lot of benefits. I was able to hack out a simple javascript interface that would let you tune into individual video streams with your browser (using ffserver to stream them from hardware) and provided some buttons to auto-generate boilerplate code and inject the API calls for performing actions like sending remote control commands when the user interacted with an on-screen remote control. So you could sit down with your test plan, run through the test, and basically have working python code for the test in the text buffer that you could just copy out to an editor to clean up. It also let us do rapid prototyping in python (The OpenCV API is pretty much the same) and convert code to C++ if it was too slow in Python. Since then I've experimented with PyBind11 instead of boost::python and at the time found the CMake integration to be a bit better. Boost's CMake integration has really come a long way in the past couple years, though, so that might no longer be the case. If you already have a boost dependency, boost::python is pretty easy to add. If you don't, something like PyBind11 is probably easier to add that all of boost or possibly even just that one little component. More on reddit.com
🌐 r/cpp
30
8
July 16, 2024
Is there a way to use a c++ project in a python project?
You can import ctypes in Python and call functions using the object file (or something along those lines). I've done this to write tests for embedded C projects for work. More on reddit.com
🌐 r/cpp_questions
21
7
December 20, 2022
🌐
pocketpy
pocketpy.dev › bindings
Write C Bindings | Portable Python 3.x Interpreter in Modern C
pkpy uses an universal signature to wrap a C function pointer as a python function or method, i.e py_CFunction.
🌐
DEV Community
dev.to › patfinder › python-cc-binding-59l6
Python C/C++ binding - Some notes - DEV Community
December 9, 2024 - Python binding is the connection between Python and external libraries or languages, allowing Python code to interface with C/C++, Java, or system-level libraries for extended functionality.
🌐
Medium
medium.com › @kapilanr2003 › a-comprehensive-walkthrough-of-python-c-binding-creation-253a6d11c1ff
A Comprehensive Walkthrough of Python/C++ Binding Creation | by Kapilan Ramasamy | Medium
August 29, 2023 - This article provides a comprehensive guide to creating Python bindings for C++ code using the pybind11 library. Python bindings enable seamless integration between C++ and Python code, allowing you to leverage C++ functionalities within your ...
🌐
Readthedocs
cppyy.readthedocs.io
cppyy: Automatic Python-C++ bindings — cppyy 3.5.0 documentation
cppyy is an automatic, run-time, Python-C++ bindings generator, for calling C++ from Python and Python from C++. Run-time generation enables detailed specialization for higher performance, lazy loading for reduced memory use in large scale projects, Python-side cross-inheritance and callbacks for working with C++ frameworks, run-time template instantiation, automatic object downcasting, exception mapping, and interactive exploration of C++ libraries.
🌐
Python
wiki.python.org › moin › IntegratingPythonWithOtherLanguages
IntegratingPythonWithOtherLanguages
Tools to make C/C++ functions/methods accessible from Python by generating binding (Python extension or module) from header files.
Find elsewhere
🌐
GitHub
github.com › Python-SIP › sip
GitHub - Python-SIP/sip: A Python bindings generator for C/C++ libraries · GitHub
SIP is a collection of tools that makes it very easy to create Python bindings for C and C++ libraries. It was originally developed in 1998 to create PyQt, the Python bindings for the Qt toolkit, but can be used to create bindings for any C or C++ library.
Starred by 62 users
Forked by 21 users
Languages: C 88.9% | Python 11.0% | C++ 0.1%
🌐
GitHub
github.com › pybind › pybind11
GitHub - pybind/pybind11: Seamless operability between C++11 and Python · GitHub
pybind11 can map the following core C++ features to Python: Functions accepting and returning custom data structures per value, reference, or pointer ... CPython 3.9+, PyPy3 7.3.17+, and GraalPy 24.1+ are supported with an implementation-agnostic interface (see older versions for older CPython and PyPy versions). It is possible to bind C++11 lambda functions with captured variables.
Author: pybind
🌐
Oxford Protein Informatics Group
blopig.com › blog › 2021 › 03 › c-python-bindings-in-5-minutes
C++ python bindings in 5 minutes | Oxford Protein Informatics Group
March 30, 2021 - This can be achieved extremely easily using pybind11, which enables us to export C++ functions and classes as importable python objects. We can do all of this very easily, without using CMake, using pybind11’s Pybind11Extension class, along with a modified setup.py.
🌐
DEV Community
dev.to › baduit › create-python-bindings-for-my-c-code-with-pybind11-2pck
Create Python bindings for my C++ code with PyBind11 - DEV Community
April 1, 2025 - Boost.Python which is kinda the predecessor of PyBind11 · Nanobind made by the creator of PyBind11, it has a similar interface, but it takes leverage of C++17 and it aims to have more efficient bindings in space and speed.
🌐
Lei Mao's Log Book
leimao.github.io › blog › Python-C-Library-Function-Binding-Using-ctypes
Python C Library Function Binding Using ctypes - Lei Mao's Log Book
January 31, 2022 - In the Python script, we created the corresponding Point class and used the pointers to objects for function calls. ... ctypes were developed for supporting C libraries, its support for C++ functions and classes are very limited. If the function and class method only returns pointers instead of custom objects, it is possible to use ctypes for C++ function and class bindings.
🌐
DeepWiki
deepwiki.com › corinwagen › pymsym › 3.2-python-c-binding-implementation
Python-C Binding Implementation | corinwagen/pymsym | DeepWiki
March 7, 2026 - For details on the underlying C library, see C Library Public API. The Python bindings provide a Pythonic interface to the libmsym C library using the ctypes foreign function interface.
🌐
Python
docs.python.org › 3 › extending › extending.html
1. Extending Python with C or C++ — Python 3.14.7 documentation
The C extension interface is specific to CPython, and extension modules do not work on other Python implementations. In many cases, it is possible to avoid writing C extensions and preserve portability to other implementations. For example, if your use case is calling C library functions or system calls, you should consider using the ctypes module or the cffi library rather than writing custom C code.
🌐
Reddit
reddit.com › r/cpp › interfacing python with c/c++ performance
r/cpp on Reddit: interfacing python with c/c++ performance
July 16, 2024 -

I want to write a heavy app with a web interface. I've been writing C++ for about three years, and I'm reluctant to give up its performance and flexibility for Python's ease of use and connectivity. I understand that sometimes C++ can pose challenges when connecting with a web interface. However, I don't want to abandon it entirely. Instead, I'm considering writing both Python and C++ in the backend of the project. My main concern is performance. Will pure C++ be significantly faster, or can I achieve comparable optimization with a combination of C++ and Python? I would appreciate any insights or experiences you have with using both languages in a project, like what Meta or PyTorch does.

Top answer
1 of 5
18
I did that for an automated video testing system I built for Comcast. We needed C++ for speed but wanted the tests to be written in Python. So all the video processing and backend stuff was written in C++ (Using ffmpeg, OpenCV and Tesseract for OCR) and the video processing libraries had a Boost::Python API to interact with the system objects. I set all the C++ objects up with JSON serialization, so you could create a C++ object in Python using JSON and that might kick some threads off to run in the background while your slow-ass python program did shit in the foreground. Overall this worked very well but it took very careful planning to make sure it did. So for example, if you wanted to tell the system to watch for an image, the API call would queue the image up in a vector internally and notify the internal components to move any images in the vector to another location to avoid blocking things for too long. Then tasks would be dispatched to thread pools to check each video frame against a copy of that image. The system had plenty of memory and we were never looking for a huge number of images, so it made sense to do it that way. Generally we were pretty close to real-time performance as long as no one did anything stupid (Like try to watch for an entire video's worth of video frames in the stream.) Once the thread pool got saturated, C++-side performance would degrade. This approach had a lot of benefits. I was able to hack out a simple javascript interface that would let you tune into individual video streams with your browser (using ffserver to stream them from hardware) and provided some buttons to auto-generate boilerplate code and inject the API calls for performing actions like sending remote control commands when the user interacted with an on-screen remote control. So you could sit down with your test plan, run through the test, and basically have working python code for the test in the text buffer that you could just copy out to an editor to clean up. It also let us do rapid prototyping in python (The OpenCV API is pretty much the same) and convert code to C++ if it was too slow in Python. Since then I've experimented with PyBind11 instead of boost::python and at the time found the CMake integration to be a bit better. Boost's CMake integration has really come a long way in the past couple years, though, so that might no longer be the case. If you already have a boost dependency, boost::python is pretty easy to add. If you don't, something like PyBind11 is probably easier to add that all of boost or possibly even just that one little component.
2 of 5
6
You can probably scale your app to 100 users in reasonably well written python, so I would say don't bother with C++ unless you want to challenge yourself. If you want to make something that works, use the language where you can move faster, which is probably Python. Don't prematurely optimize by bringing in extra complexity and a second language. If you find your app is too slow, you can still move stuff out to native code later.
🌐
Medium
medium.com › @ahmedfgad › pybind11-tutorial-binding-c-code-to-python-337da23685dc
Pybind11 Tutorial: Binding C++ Code to Python | by Ahmed Gad | Medium
December 11, 2024 - The PYBIND11_MODULE macro defines the module given the name example. To bind individual functions, the def() method is used. Each bound function is given a Python-accessible name, a reference to the C++ implementation, and optional docstrings for better clarity in Python.
🌐
SegmentFault
segmentfault.com › a › 1190000040312118 › en
Python binding: call C or C++ from Python - 开发者之家 - SegmentFault 思否
July 8, 2021 - Summary: Are you a Python developer who has a C or C++ library that you want to use from Python? If so, then the Python binding allows you to call functions and pass data from Python to C or C++, allowing you to take advantage of the advantages ...
🌐
Reddit
reddit.com › r/cpp_questions › is there a way to use a c++ project in a python project?
r/cpp_questions on Reddit: Is there a way to use a c++ project in a python project?
December 20, 2022 -

I have a relevant c++ project called Giraffe from https://github.com/ianfab/Giraffe

I need a specific function within the project to run in another project written in python. Does anyone know how to do this? The function is found under ann/features_conv however it has dependencies on other files as well.

Edit: Im a total beginner in c++ and have no idea what to do with c++ project files. Would appreciate it if more detailed instructions can be given. Thanks!!!

🌐
Python Software Foundation
wiki.python.org › python › IntegratingPythonWithOtherLanguages.html
C/C++ Binding Generators - Python Wiki
Tools to make C/C++ functions/methods accessible from Python by generating binding (Python extension or module) from header files.