从嵌入式Python加载ZIP中的pyd文件

8 投票
4 回答
4336 浏览
提问于 2025-04-17 08:50

我可以通过在 Python 解释器中调用 "import some_module" 来从一个 zip 文件加载 Python 模块(.py, .pyc, .pyd),前提是我先把 sys.path 扩展到包含这个 zip 文件,并且我还需要先运行

import zipextimporter
zipextimporter.install()

后者是加载 .pyd 模块所必需的。

我还可以从嵌入在 C++ 中的 Python 加载 .py 和 .pyc 模块。不过,为了从嵌入的 Python 中加载 .pyd 模块,我添加了

PyRun_SimpleString("import zipextimporter");

这个 C++ 程序在这行之后运行没有错误。但是接下来的命令

PyRun_SimpleString("zipextimporter.install()");

却给了我这个错误:

enter image description here

为什么在嵌入 Python 时 zipextimporter.install() 会崩溃?

我该如何解决这个问题?

这可能和 C++ 代码的编译方式有关吗?我使用的是 g++:

g++ embed-simple.cpp -IE:\Python27\include -LE:\Python27\libs -lpython27 -o embed-simple

我看到一个链接 如何用 mingw gcc 链接 msvcr90.dll?

这可能提供解决方案吗?如果可以,我该如何调整,gcc-->g++,因为我在运行 C++ 代码,而不是 C。

我在 WinXP 上运行 Python 2.7.2。

在干净安装 Python 2.7.2 后,我没有遇到运行时错误,只出现了这个:

导入错误:没有名为....的模块

嵌入的 C++ 脚本的编译方式会有影响吗?我使用了 g++。我也用英特尔编译器编译过,但也出现了同样的运行时错误。也许我应该试试 MS Visual C++。

或者用 ctypes 来导入 pyd?

4 个回答

3

memimporter.pyd这个文件(它在zipextimporter里面)是为哪个版本的Python编译的呢?如果Python解释器和这个pyd文件不匹配,你可能会遇到很严重的崩溃问题。

我不太确定memimporter的代码在哪里,但我猜这个代码的目的是插入一个导入钩子,它可以检测到基于zip的pyd导入,然后把这个pyd文件提取到一个临时位置,再调用Python解释器的标准导入功能来处理它。

4

PYD文件其实就是改了名字的本地DLL文件。加载这些文件需要依赖操作系统的功能和一些限制。

比如说,Windows XP或者我知道的任何操作系统,都无法直接从ZIP压缩文件中加载DLL文件,所以你也不能从ZIP文件中加载PYD文件。

6

memimporter 和 zipextimporter 确实可以直接从内存或压缩文件中加载 .pyd 文件,而不需要先把它们解压到文件里。

运行时错误 R6034 是因为 VC9 运行库必须通过一个清单文件来加载。如果你在 Python 2.5 中运行你的代码,因为它使用的是不同的 C 运行库,可能就会成功。我猜你需要在你的可执行文件中嵌入一个引用 VC9 运行库的清单文件;也许 py2exe 的维基页面能给你一些帮助。

撰写回答