The operating system is Windows 10.
I downloaded the installer for Python 3.12.3 from https://www.python.org/downloads/.
During custom installation, I chose a install location: D:ProgramsPythonPython312
After installation, I confirmed that the D:ProgramsPythonPython312
directory exists, and that python.exe
is in it. No Windows environment variables were changed by the installation.
I did not establish any Python virtual environments.
In Visual Studio 2017, I created a new C++ Windows console application project, named runpy
. I changed the project settings so that it can find headers and libraries for the Python version I installed. The following changes are sufficient for the app to compile and link.
- In C/C++ > General > Additional Include Directories, added:
D:ProgramsPythonPython312include
- In Linker > General > Additional Library Directories, added:
D:ProgramsPythonPython312libs
Also, I manually copied python312_d.dll
to the output directory of the app. i.e., from D:ProgramsPythonPython312
to D:workrunpyx64Debug`. I will make that a postbuild step in the project later. That is sufficient for the app to run.
I attempted to embed Python in the C++ app with the following code.
// Precompiled header includes other stuff not relevant to embedding Python.
#include "stdafx.h"
// Standard stuff
#include <iostream> // std::cout
// Python
#include <Python.h>
void on_PyStatusException( PyStatus const & status )
{
std::cout << "PyStatus.func: " << ( status.func ? status.func : "n/a" ) << std::endl;
std::cout << "PyStatus.err_msg: " << ( status.err_msg ? status.err_msg : "n/a" ) << std::endl;
Py_ExitStatusException( status );
}
int main( int argc, char * argv[] )
{
printf( "Howdy this is a C++ app that embeds Pythonn");
PyStatus status;
PyConfig config;
//------------------------------
// Sets config.isolated to 1, and other stuff.
// But not sufficient by itself.
PyConfig_InitIsolatedConfig( &config );
// Unknown if important. Returns a successful status.
status = PyConfig_Read( &config );
// Provide an explicit path to the Python executable. Returns a successful status.
wchar_t * pythonPath = L"D:\Programs\Python\Python312\python.exe";
status = PyConfig_SetString( &config, &config.executable, pythonPath );
//------------------------------
// Does *not* work. Returns a failure status.
status = Py_InitializeFromConfig( &config );
if ( PyStatus_Exception( status ) )
{
on_PyStatusException( status );
}
//------------------------------
// Cleanup.
PyConfig_Clear( &config );
return 0;
}
However, Py_InitializeFromConfig()
fails with the following output.
Python path configuration:
PYTHONHOME = (not set)
PYTHONPATH = (not set)
program name = 'python'
isolated = 1
environment = 0
user site = 0
safe_path = 1
import site = 1
is in build tree = 0
stdlib dir = 'D:workrunpyLib'
sys._base_executable = 'D:\Programs\Python\Python312\python.exe'
sys.base_prefix = 'D:\work\runpy'
sys.base_exec_prefix = 'D:\work\runpy'
sys.platlibdir = 'DLLs'
sys.executable = 'D:\Programs\Python\Python312\python.exe'
sys.prefix = 'D:\work\runpy'
sys.exec_prefix = 'D:\work\runpy'
sys.path = [
'D:\work\runpy\x64\Debug\python312_d.zip',
'D:\work\runpy',
'D:\work\runpy\Lib',
'D:\work\runpy\x64\Debug',
]
PyStatus.func: init_fs_encoding
PyStatus.err_msg: failed to get the Python codec of the filesystem encoding
Several of the Python path configuration settings in the above output are clearly wrong. They point to the directory of the runpy
app, instead of to Python stuff. What other PyConfig
properties should I established so that Py_InitializeFromConfig()
will succeed?
I have been following examples in other StackOverflow posts and the https://docs.python.org documentation, but I cannot find the correct combination.