23

我在 Windows 上开发,我到处搜索,没有找到任何人谈论这种事情。

我在桌面上制作了一个使用 MSVC 嵌入 Python 3.1 的 C++ 应用程序。我链接了 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 上更严重,但我已经看到许多在本地嵌入 Python 的 Windows C/C++ 应用程序,我不确定它们是如何做到的。

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

非常感谢您提前。

4

4 回答 4

24

除了pythonxy.dll,你还需要整个Python库,即lib文件夹的内容,加上扩展模块,即DLLs文件夹的内容。如果没有标准库,Python 甚至无法启动,因为它会尝试查找 os.py(在 3.x 中;在 2.x 中为 string.py)。在启动时,它会导入一些模块,特别是 site.py。

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

你可以自由地从你不需要的东西中剥离图书馆;有各种静态计算依赖关系的工具(尤其是模块查找器)。

如果你想最小化文件的数量,你可以

  1. 将所有扩展模块静态链接到您的 pythonxy.dll,甚至将 pythonxy.dll 静态链接到您的应用程序
  2. 使用冻结工具;这将允许将标准库的字节码链接到您的 pythonxy.dll 中。
  3. (替代 2.)将 pythonxy.zip 用于标准库。
于 2009-09-07T07:16:51.650 回答
13

好的。如果您不想压缩,请将 Python26\DLLs & Python26\lib 复制到您的 exe 目录,如下所示:

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

然后使用 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;
}

很好,搜索路径是相对于 exe 的。Py_GetPath 可以告诉你它在哪里寻找模块。

于 2010-06-03T23:02:34.060 回答
6

Python 标准库的 zip 对我来说适用于 Python27。

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

我将那个 zip 和 python27.dll 与可执行文件一起复制了。

于 2012-02-02T16:25:54.490 回答
6

我想为其他可能仍然遇到问题的人添加一些额外的信息,就像我一样。我最终能够使用用户 sambha 提出的方法使我的应用程序正常工作,即:

程序文件 (x86)\
    我的应用程序文件夹\
        我的应用程序.exe
        python27.dll
        蟒蛇27\
            DLLs\(DLLs 文件夹的内容)
            Lib\(Lib 文件夹的内容)

...还有一个重要的补充:我还需要安装 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,它也不起作用。

于 2012-09-21T23:39:36.323 回答