从嵌入式python的zip中加载pyd文件

时间:2011-12-22 09:38:24

标签: python visual-c++ zip py2exe cython

我可以通过调用“import some_module”从zip文件加载Python模块(.py,.pyc,.pyd) 只有在扩展了sys.path以包含zip文件之后才能从Python解释器中获取 并且只有在我运行之后

import zipextimporter
zipextimporter.install()

.pyd模块需要后者。

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

PyRun_SimpleString("import zipextimporter");

C ++ exe超出此行而没有错误。但是下一个命令

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

我看到了一个链接 How to link against msvcr90.dll with mingw gcc?

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

我在WinXP上运行Python 2.7.2。

在干净安装Python 2.7.2后,我没有收到运行时错误,只是这样:

  

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

嵌入C ++脚本的编译方式是否重要?我用过g ++。我也 使用英特尔编译器编译,但是给出了相同的运行时错误。也许我应该尝试MS Visual C ++。

或者使用ctypes导入pyd?

4 个答案:

答案 0 :(得分:5)

memimporter和zipextimporter确实能够从内存/ zip-archives中加载.pyd文件,而无需将它们解压缩到文件中。

runtimerror R6034是由必须通过清单加载VC9运行时库引起的。在Python 2.5中运行代码,使用不同的C运行时,很可能会成功。我想你必须在你的exe中嵌入一个引用VC9运行时库的清单;也许py2exe wiki可以提供一些指导。

答案 1 :(得分:4)

PYD文件是具有重命名扩展名的本机DLL文件。加载它们依赖于操作系统设施和操作系统限制。

据我所知,Windows XP或任何操作系统无法从ZIP文件加载DLL文件,因此您无法从ZIP文件加载PYD文件。

答案 2 :(得分:2)

哪个版本的python是memimporter.pyd(在zipextimporter里面)编译的?如果python解释器和pyd不匹配,你将会发生可怕的崩溃。

我不确定mem导入程序代码在哪里,但我猜想我会想到插入一个导入钩子来检测基于zip的pyd导入并将pyd提取到临时位置并调用Python解释器的标准导入。

答案 3 :(得分:2)

这听起来像我尝试使用py2exe编译应用程序的同类问题。看这里: http://www.py2exe.org/index.cgi/Tutorial,请参阅第5.2节。同样的事情发生...第一次尝试使用memimporter时,它会崩溃并出现类似的错误消息。基本上,对于python 2.6+,您需要在路径中拥有运行时库的确切版本,以及指向它的清单。由于你使用的是嵌入式python,我不知道它是如何工作的,但也许这会让你更接近。

我首先将运行符dll的'正确'版本放在某处,并在python代码中,在导入zipextimporter之前,将正确运行时的路径附加到sys.path并查看是否修复了它。不知道如何获得嵌入式python的清单。它可能需要包含在父应用程序的清单中。

编辑:顺便说一下,我忘记了,我们也找到了解决这个问题的另一种方法。我忘记了确切的细节,但是会发生什么是你的应用程序加载运行时的默认版本,然后python要求它的版本,它在c:\ python {26,27}中找到一个并且它不匹配。解决此问题的最简单方法是删除c:\ python \ msvcr90.dll。然后,python将不会访问可能无法与您的应用程序清单一起使用的本地(旧)版本的dll,并且它们都必须从Windows目录中获取当前版本,这将匹配。