Calling Python from C++ and back
Imagine the following situation:
- You have a existing C++ application. You want to migrate parts of it to python. That is, you want to be able to call python code from C++ code.
- You also want to be able to call C++ code from python.
- Your C++ code is multithreaded and there is no guarantee that any one thread calling python has initialized the interpreter.
- You need to distribute the resulting app with minimum overhead.
Enter pyfromc. It is a sample Win32 C++ application using an embedded python interpreter, to be used as a potential starting point.
Download
You can download pyfromc here. Note that the installer is only 692.031 bytes large, but includes the c++ sample app, the embedded python interpreter and the full sourcecode.
License
There is none. Use at own risk.
Calling Python from C++
pyfromc.py
is a sample python code that exposes two global functions, test
and dumpmods
. The C++ class Python
inside pyfromc.cpp/.h
defines
wrapper methods for these calls. E.g. if you want to add a new method to pyfromc.py
,
you must also define a wrapper method in pyfromc.h
and implement it in pyfromc.cpp
.
The C++ wrapper method uses the helper class PythonCall
, which in turn uses
techniques described in the Python manual, section
Embedding Python in Another Application.
Calling C++ from Python
Basically, cfrompy.cpp
is a standard python module, as described in the
python manual, section Extending Python with C or C++ .
The only difference is that cfrompy.cpp is not a DLL, it is part of the executable code you
write, so you have easier access to your existing C++ code.
Thread safety
The code is (or rather: should be) threadsafe. That is, you should be able to call python code from any native Win32 thread, without any additional precautions (provided your C++ code is already threadsafe). The code uses the techniques described in PEP 311 - Simplified Global Interpreter Lock Acquisition for Extensions.
Distribution your app
Starting with python 2.3, you can distribute modules in a zipfile, called "python23.zip", which must be in the same directory as python23.dll. So, what you need is
- Your C++ app
- python23.dll
- all modules you need encoded in python23.zip
- all .pyd extensions you need (cannot be stored in python23.zip because loaded as a DLL)
The only problem is: how to find out what modles you need. Well, enter dumpmods.py
,
a small python script that enumerates all loaded modules and dumps them into a target directory.
Usage: When your program ends, add these two lines:
import dumpmods
dumpmods.analyze_modules(path to store files in)
where "path to store files in" has obvious connotations.