如何使用C++或Python编程列出DLL的依赖项?

4

我正在使用Boost Python为C++项目编写Python接口,如果缺少DLL,Python会给出一个非常不友好的错误消息:

ImportError: DLL load failed: 找不到指定的模块。

根据此网站的说法,无法显示更多信息。

现在,最大的问题是,我们不能使用依赖项检查器或dumpbin,因为我们需要能够通过编程方式确定缺少哪个DLL。好消息是,我们只需要检查第一层依赖关系。因此,如果my.exe依赖于a.dll、b.dll和c.dll,那么这就是我们感兴趣的DLL集合。如果a、b和c都在它们应该在的地方,那么我的工作就完成了。

我已经找到了这个MSDN页面上枚举正在运行的进程,但是无法找到如何对非运行中的.exe或未加载的.dll执行此操作。我最接近的一篇文章是关于LoadLibraryEx函数的MSDN文章*。然而,我无论如何都无法弄清楚如何从返回的HMODULE获取依赖项表。

所以,64,000美元的问题是:我如何从HMODULE获取.exe/.dll依赖项?更好的问题是:那是我获取依赖项的地方吗?如果不是,那么我在哪里可以找到它?

最理想的解决方案是使用C ++,但我们也很乐意使用Python解决方案。任何帮助或建议都将不胜感激。谢谢。

*我会链接这篇文章,但我的声望还不够高,无法在一个问题中发布两个链接。 :)


你在构建dll时链接的Python版本是否与运行它的版本相同?exe文件所在的文件夹中是否包含所有必需的dll(例如Boost)或者这些dll可在%PATH%中找到?此外,要注意32位/64位不匹配的情况。 - CristiFati
我们从未遇到过 Boost 或 Python DLL 缺失的问题。问题在于,由于某种原因,一个被包含的库不在那里。例如,我们使用 boost python 包装库 A,但是库 A 的 DLL 不在它应该在的位置。我们只会收到上述错误,而不是类似于“找不到 a.dll”的错误信息。 - soulsabr
你使用的是哪个版本的_Python_?你有安装pywin32吗?所以,你正在尝试导入一个由_C_编写的模块(_.pyd_),它依赖于一组库,其中一个可能不存在,但你想以编程方式确定哪个库不存在。如果是这种情况,由于HMODULE对象的存在(与NULL不同),意味着dll已经成功加载,因此无法使用HMODULE - CristiFati
是的,pywin32。 好的,我不知道只有当所有DLL依赖项都存在时才会得到HMODULE。我们都知道MSDN文档有多好。这对于将来很有用。感谢这些信息。希望Nick Cano的建议对我有所帮助。 - soulsabr
1个回答

4

您需要阅读模块的可移植可执行文件头(PE Header)。这是一种结构,描述了二进制文件所依赖的导入、导出、重定位、节、资源、代码、静态数据以及其他所有内容。虽然它可以直接解析,但是PE Header结构具有许多不明显的怪癖和细微差别。我建议使用PeLib等库来处理所有内容。


下载了PeLib。等我试用一下后再告诉你效果如何。如果不行,至少现在我了解了PE头部信息。编辑:我距离能够给您点赞还差4个声望值。 - soulsabr
不用担心声望问题 :) 如果你在使用PeLib时遇到了问题(它是一个有点混乱的模板重型库,所以可能会有点令人沮丧),而你仍然愿意使用Python,那么你可以尝试类似于这个或者这个的东西。 - Nick Cano
哈哈,升级了!+1 给你。我已经编译了 PeLib。出于某种奇怪的原因,他们用宏重新定义了“for”。VS2013 不喜欢那样做。无论如何,感谢提供链接。我会好好看一遍所有内容。即使 PeLib 能够完成工作,其他工具在未来也可能派上用场。谢谢。 - soulsabr
它可以工作!是的,PeLib很混乱。他们重新定义事物,看起来没有明显的原因,但它可以工作。它为我列出了所有的DLL依赖项,并且一旦编译完成后使用起来并不是非常麻烦。谢谢,这将节省我大量的时间。 - soulsabr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接