使用Python嵌入的C++:如果未安装Python,则会崩溃

apo*_*est 22 c++ python embed dll distribution

我正在Windows上开发,我搜索到的所有地方都没有找到任何人谈论这种事情.

我在桌面上制作了一个C++应用程序,它使用MSVC嵌入了Python 3.1.我将python31.lib与应用程序运行文件夹中的python31.dll一起包含在可执行文件中.它很棒.我的扩展和嵌入代码肯定有效,没有崩溃.

我将run文件夹发送给没有安装Python的朋友,在脚本设置阶段,应用程序崩溃了.

几个小时前,我在安装了Python 2.6的笔记本电脑上试用了这个应用程序.我得到了与我的朋友相同的崩溃行为,并通过调试发现它是Py_Initialize()调用失败.

我在笔记本电脑上安装了Python 3.1而没有更改应用程序代码.我跑了它,它完美运行.我卸载了Python 3.1并且应用程序再次崩溃.我在我的应用程序中放入代码以从本地python31.dll动态链接,以确保它正在使用它,但我仍然得到崩溃.

我不知道解释器是否需要比DLL更多启动或什么.我无法找到任何资源.Python文档和其他指南似乎没有解决如何在不让用户在本地安装Python的情况下分发使用Python嵌入的C/C++应用程序.我知道它在Windows上比在Unix上更多的是一个问题,但是我已经看到许多在本地嵌入Python的Windows C/C++应用程序,我不确定它们是如何做到的.

除了DLL之外我还需要什么?为什么我安装Python然后在卸载时停止工作呢?听起来应该是如此微不足道; 也许这就是没有人真正谈论它的原因.不过,我无法解释如何处理这个崩溃问题.

非常感谢你提前.

Mar*_*wis 23

除了pythonxy.dll之外,您还需要整个Python库,即lib文件夹的内容,以及扩展模块,即DLLs文件夹的内容.没有标准库,Python甚至不会启动,因为它试图找到os.py(在3.x中; 2.x中的string.py).在启动时,它会导入许多模块,特别是site.py.

它有不同的位置搜索标准库; 在您的情况下,它最终在注册表中找到它.之前,使用可执行文件名(通过Py_SetProgramName设置)试图找到里程碑; 它还检查文件python31.zip,它应该是标准库的压缩副本.它还检查环境变量PYTHONHOME.

你可以自由地从你不需要的东西中剥离图书馆; 有各种静态计算依赖关系的工具(特别是modulefinder).

如果要最小化文件数,可以

  1. 将所有扩展模块静态链接到pythonxy.dll,甚至将pythonxy.dll静态链接到您的应用程序中
  2. 使用冻结工具; 这将允许将标准库的字节代码链接到pythonxy.dll.
  3. (或2.)使用pythonxy.zip作为标准库.


sam*_*bha 12

尼斯.如果您不想压缩,请将Python26\DLLs和Python26\lib复制到您的exe目录,如下所示:

.\myexe.exe       
.\python26.dll
.\Python26\DLLs
.\Python26\lib
Run Code Online (Sandbox Code Playgroud)

然后使用Py_SetPythonHome()API设置PYTHONHOME.显然,此API不在Py_Initialize()之前的"允许"调用列表中;

以下在Windows上工作(Python未安装):

#include "stdafx.h"
#include <iostream>
#include "Python.h"

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
   char pySearchPath[] = "Python26";
   Py_SetPythonHome(pySearchPath);
   Py_Initialize();
   PyRun_SimpleString("from time import time,ctime\n"
                     "print 'Today is',ctime(time())\n");
   //cerr << Py_GetPath() << endl;
   Py_Finalize();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

很好,搜索路径是相对于exe的.Py_GetPath可以显示它在哪里寻找模块.


小智 6

Python标准库的zip文件适用于Python27.

我压缩 Lib和dll 的内容,并确保没有额外的python27子文件夹或Lib或dll子文件夹.即只是一个名为python27.zip的zip包含所有文件.

我复制了该zip和python27.dll以及可执行文件.


dja*_*ude 6

我想为那些可能仍然遇到麻烦的人添加一些额外的信息,就像我一样.我最终能够使用用户sambha提出的方法使我的应用程序工作,即:

Program Files (x86)\
    MyApplicationFolder\
        MyApplication.exe
        python27.dll
        Python27\
            DLLs\ (contents of DLLs folder)
            Lib\ (contents of Lib folder)

...还有一个重要的补充:我还需要安装MSVCR90.DLL.我使用的是Python 2.7,显然python27.dll需要MSVCR90.DLL(以及其他MSVC*90.DLL).

我通过从http://www.microsoft.com/en-us/download/details.aspx?id=29下载,安装和运行'vcredist_x86.exe'软件包解决了这个问题.我认为,虽然我不确定,你需要以这种方式至少在Win7上这样做,而不是简单地将MSVC*90.DLL放在您的.exe旁边,就像过去一样.Microsoft安装程序放置文件并在Win7下以特殊方式注册它们.

我也尝试过.zip文件方法,但即使安装了MSVCR90.DLL也不行.