*.pyd 文件加载失败,但依赖walker正常,ProcMon显示已加载

5 投票
3 回答
10746 浏览
提问于 2025-04-16 15:45

我正在尝试用Python加载一个*.pyd文件,但遇到了一个常见的错误:“导入错误:DLL加载失败:找不到指定的过程。”

我已经做了以下几件事:

1.) 用Dependency Walker检查了这个*.pyd文件。发现GPSVC.DLL和IESHIMS.DLL缺失,但它们是延迟加载的;IEFRAME.DLL也缺失了一个导出,但同样是延迟加载的。我的理解是这些文件并没有被使用,而且是延迟加载的,所以它们应该不是问题所在。

2.) 在Python命令窗口中对foo.pyd进行了“import foo”,同时用ProcMon监控。ProcMon显示在“foo.pyd”上有一个“LoadImage”的事件,结果是成功。

这似乎意味着*.pyd文件加载得很正常。

那么我到底漏掉了什么呢?我的Windows诊断工具告诉我一切正常,但Python却说这个东西无法加载(通常是因为缺少DLL或符号)。

有什么想法吗?

谢谢!

3 个回答

1

如果你有一个文件叫 foo.pyd,那么要让 import foo 成功运行,里面必须有一个可以被外部访问的函数,名字叫 initfoo。如果这个函数存在,使用 Dependency Walker 工具可以看到它(通常这是唯一的函数)。Python 需要调用 initfoo 来初始化 foo 模块。

注意:如果真的是这个问题,我会期待看到一个更明确的错误信息:

>>> import fubar
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: dynamic module does not define init function (initfubar)
>>>

你说你在“尝试加载一个 *.pyd 文件”。这只是描述 import foo 的一种奇怪方式,还是说有其他的意思?

你是自己创建这个 pyd 文件的吗?如果不是,那是谁做的?你问过他们吗?这个 pyd 文件在网上能找到吗,其他人能试着加载/导入它吗?

2

好的,下面是答案:

Windows的诊断工具(比如depends和procmon等)显示DLL(或者pyd文件)加载得很好。

但是Python显示它没有加载成功。

我发现Windows工具指向了一个隐藏在C:\Windows\SysWOW64文件夹里的不同版本的Python26.dll。

这个在SysWOW64里的第二个Python26.dll有一个符号,而主安装的python26.dll(通过Windows的Python安装程序安装,位于C:\Python26)里没有这个符号。

这个符号叫做“_PyByteArray_empty_string”,显然是我的*.pyd文件需要的。

所以,当通过Windows的诊断工具加载时,找到了SysWOW64里的DLL,*.pyd文件加载得很顺利。而当从Python加载时,找到了C:\Python26\里的DLL,因为缺少这个符号,所以加载失败了。

这就是问题出现的原因。现在的问题是:为什么会有两个版本的Python26.dll,一个有“_PyByteArray_empty_string”,一个没有呢?

我使用的是Python 2.6.6。也许这个符号在2.6.6版本中被去掉了,但在某些旧的2.6.x版本中存在?

5

你使用的 .pyd 文件和你的 Python 版本是一样的吗?如果你加载了一个不适合你 Python 版本的 .pyd 文件,就可能会出现那个错误提示。

你可以用 Dependency Walker 工具来查看它链接的是哪个 pythonNN.dll 文件。

撰写回答