Quick note on how to include Python into a C++ executable built with Visual Studio 2022. Uses Python installed via the Windows Store.
- Locate Python installation
Easiest way I found was from Powershell, run python: import sys; print(sys.__file__)
Because my installation was from Windows Store, it was in c:/Program Files/WindowsApps
which was not accessible to my user. From Powershell
(run as Admin) I had to run takeown /f "C:\Program Files\WindowsApps" /r
.
- Add includes to Visual Studio project
Under project properties -> C/C++ -> Additional Include Directories. The directory was C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python3.10_3.10.3056.0_x64..blah..\include
.
- Add libs
Under the build target's properties, Linker. The directory was same as includes but \libs
at the end not include
.
- Include the Python headers in your code
Just #include <Python.h>
didn't work - it was asking for a library that didn't exist, like python310_d.dll
. Apologies to whoever on Stackoverflow I pulled this from and then lost the page,
#ifdef _DEBUG
#undef _DEBUG
#include <Python.h>
#define _DEBUG
#else
#include <Python.h>
#endif
- Add the DLL somewhere accessible to the built executable
Copy python310.dll
into the same directory as the .sln
file.
- Ensure environment variables include stuff necessary for the Python runtime
You need to point the executable to the actual Python dir on the system as well as its standard library. You can run the .exe in an environment with these set, or set them from C++:
include <stdlib.h>
putenv("PYTHONHOME=C:\\Program Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64...blah");
putenv("PYTHONPATH='C:\\Program Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64..blah..\\Lib'");
Note, the second folder is Lib
capital L, there are .py
files and modules there whereas the libs
folder from step 3 is compiled binaries.
- Do something in Python
Here's a simple snippet to create a function, call it, and display the return value:
Py_Initialize();
PyObject* main = PyUnicode_FromString("__main__");
PyObject* moduleMain = PyImport_Import(main);
PyRun_SimpleString(
"def say_hello(to):\n"\
" return 'hello ' + to\n"
);
PyObject* func = PyObject_GetAttrString(moduleMain, "say_hello");
auto inputs = PyUnicode_FromString((const char*)"tom");
PyObject* args = PyTuple_Pack(1, inputs);
PyObject* result = PyObject_CallObject(func, args);
if (Py_FinalizeEx() != 0) {
DBG("An error ocurred");
}
std::string s = PyUnicode_AsUTF8(result);
cout << s;