带有Python嵌入的C ++:如果未安装Python,则崩溃

问题描述 投票:22回答:4

我正在Windows上进行开发,并且我到处搜索时都找不到任何人在谈论这种事情。

我在桌面上制作了一个C ++应用,该应用使用MSVC嵌入了Python 3.1。我链接了python31.lib,并将python31.dll包含在应用程序的运行文件夹中以及可执行文件旁边。效果很好。我的扩展程序和嵌入代码肯定有效,并且没有崩溃。

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

几个小时前,我在装有Python 2.6的笔记本电脑上尝试了该应用程序。我的崩溃行为与朋友相同,并且通过调试发现失败的原因是Py_Initialize()调用。

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

我不知道解释器是否需要比DLL更多的启动信息。我至今无法找到任何资源。 Python文档和其他指南似乎从未解决如何在不让用户在本地安装Python的情况下分发使用Python嵌入的C / C ++应用程序的问题。我知道Windows上的问题比Unix上的更多,但是我已经看到许多Windows C / C ++应用程序在本地嵌入Python,而且我不确定它们的工作方式。

除了DLL以外,我还需要什么?为什么在安装Python时它能工作,而在卸载它时却停止工作?听起来应该很琐碎;也许这就是为什么没人真正谈论它。但是,我无法真正解释如何处理此崩溃问题。

非常感谢。

python c++ dll embed
4个回答
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用于标准库。

12
投票

不错。如果不想压缩,则将Python26 \ DLLs和Python26 \ lib复制到您的exe目录中,如下所示:

.\myexe.exe       
.\python26.dll
.\Python26\DLLs
.\Python26\lib

然后使用Py_SetPythonHome()API设置PYTHONHOME。显然,此API不在“允许的”调用列表中[[before 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; }
很好,搜索路径与exe是相对的。 Py_GetPath可以向您显示所有模块的位置。 

6
投票
Python标准库的zip与Python27一起为我工作。

我压缩了Lib和dll的

内容,并确保没有其他python27子文件夹或Lib或dll子文件夹。即只是一个名为python27.zip的zip文件,其中包含所有文件。

我在可执行文件旁边复制了该zip和python27.dll。

6
投票
和我一样,我想为其他可能仍然遇到麻烦的人添加一些其他信息。最终,我可以使用用户sambha提出的方法来使我的应用程序正常工作,即:

程序文件(x86)\MyApplicationFolder \MyApplication.exepython27.dllPython27 \DLLs \(DLLs文件夹的内容)Lib \(Lib文件夹的内容)

...带有一个

important另外:我还需要安装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,也无法使用。

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