如何在 Windows C++ 应用程序中嵌入 Python 3.12?

问题描述 投票:0回答:1

操作系统是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 版本的标头和库。 以下更改足以让应用程序编译和链接。

  • 在 C/C++ > 常规 > 附加包含目录中,添加:
    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 c++ python-3.x embed
1个回答
0
投票

Python 需要知道它的标准库在哪里,为了运行 python,你需要整个

Python12
文件夹,而不仅仅是
python312.dll
,并且你需要在启动时使用 Py_SetPythonHome

设置它的路径
    wchar_t pythonPath[]  = L"D:\\Programs\\Python\\Python312";
    Py_SetPythonHome(pythonPath);

为了制作更小的包,您可以将其中的所有

.py
文件复制到 zip 文件中,因为 python 可以从
.py
文件加载
.zip
文件,但是那里的
.pyd
文件需要一起运送对于你的可执行文件,有办法删除它的一部分。

© www.soinside.com 2019 - 2024. All rights reserved.