操作系统是Windows 10。
我从 https://www.python.org/downloads/ 下载了 Python 3.12.3 的安装程序。 在自定义安装过程中,我选择了安装位置:
D:\Programs\Python\Python312
安装后,我确认
D:\Programs\Python\Python312
目录存在,并且python.exe
在其中。 安装没有更改 Windows 环境变量。
我没有建立任何Python虚拟环境。
在 Visual Studio 2017 中,我创建了一个新的 C++ Windows 控制台应用程序项目,名为
runpy
。 我更改了项目设置,以便它可以找到我安装的 Python 版本的标头和库。 以下更改足以让应用程序编译和链接。
D:\Programs\Python\Python312\include
D:\Programs\Python\Python312\libs
此外,我手动将
python312_d.dll
复制到应用程序的输出目录。 即从 D:\Programs\Python\Python312
到 D:\work\runpy\x64\Debug
。 稍后我会将其作为项目中的构建后步骤。 这足以让应用程序运行。
我尝试使用以下代码将 Python 嵌入到 C++ 应用程序中。
// 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 Python\n");
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;
}
但是,
Py_InitializeFromConfig()
失败并显示以下输出。
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:\work\runpy\Lib'
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
上述输出中的几个 Python 路径配置设置明显错误。 它们指向
runpy
应用程序的目录,而不是 Python 内容。 我还应该建立哪些其他 PyConfig
属性才能使 Py_InitializeFromConfig()
成功?
我一直在关注其他 StackOverflow 帖子和 https://docs.python.org 文档中的示例,但我找不到正确的组合。
Python 需要知道它的标准库在哪里,为了运行 python,你需要整个
Python12
文件夹,而不仅仅是 python312.dll
,并且你需要在启动时使用 Py_SetPythonHome 设置它的路径
wchar_t pythonPath[] = L"D:\\Programs\\Python\\Python312";
Py_SetPythonHome(pythonPath);
为了制作更小的包,您可以将其中的所有
.py
文件复制到 zip 文件中,因为 python 可以从 .py
文件加载 .zip
文件,但是那里的 .pyd
文件需要一起运送对于你的可执行文件,有办法删除它的一部分。