如何以编程方式列出 C++ 或 Python 中的 DLL 依赖项?

Posted

技术标签:

【中文标题】如何以编程方式列出 C++ 或 Python 中的 DLL 依赖项?【英文标题】:How do I programmatically list a DLL's dependencies in C++ or Python? 【发布时间】:2015-11-23 22:06:16 【问题描述】:

我目前正在使用 Boost Python 为 C++ 项目编写 Python 接口。问题是,如果缺少 DLL,Python 会给我们一个非常无用的错误消息:

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

根据this site,不可能显示比这更多的信息。

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

我已经找到this MSDN page on enumerating for a running process,但无法找到如何为非运行的 .exe 或已卸载的 .dll 执行此操作。我最接近的是关于 LoadLibraryEx 函数*的 MSDN 文章。但是,我一生都无法弄清楚如何从返回的 HMODULE 中获取依赖表。

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

最佳解决方案是 C++,但我们也很高兴有一个 Python 解决方案。任何帮助或建议将不胜感激。谢谢。

* 我会链接文章,但我的代表不够高,无法在一个问题中发布两个链接。 :)

【问题讨论】:

您在构建 dll 时链接的 Python 与您运行它时使用的相同?是否有所有必需的 dll(例如 Boost )与 exe 位于同一文件夹中(或在 %PATH% 的某个地方可用?)另外,请注意 32/ 64 位不匹配。 我们从未遇到过缺少 Boost 或 Python DLL 的问题。问题是,由于某种原因,一个合并的库不存在。例如,我们使用 boost python 包装库 A,而库 A 的 DLL 不在它应该在的位置。我们只收到上述错误,而不是“找不到 a.dll”。 您使用的是什么Python?你有没有安装过pywin32?因此,您正在尝试导入一个用 C 编写的模块 (.pyd),该模块依赖于一组库,其中一个可能不存在,但您想以编程方式确定哪一个。如果是这种情况,则不能使用HMODULE,因为HMODULE 对象的存在(不同于NULL)意味着dll 已经成功加载。 是的,pywin32。好的,我不知道如果所有 DLL 依赖项都存在,我只会得到一个 HMODULE。我们都知道 MSDN 文档有多棒。知道这对未来很好。谢谢(你的)信息。希望尼克卡诺的建议对我有用。 【参考方案1】:

你需要阅读模块的Portable Executable Header(PE Header)。这是一个描述导入、导出、重定位、部分、资源、代码、静态数据以及二进制文件所依赖的所有其他内容的结构。虽然可以直接解析,但 PE Header 结构有很多不明显的怪癖和细微差别。我建议使用诸如 PeLib 之类的库来为您处理一切。

【讨论】:

已下载 PeLib。我会让你知道它对我来说是如何工作的。如果没有别的,至少现在我知道 PE Header。编辑:我距离能够给你一个 +1 还差 4 个代表。 不用担心代表 :) 如果您在使用 PeLib 时遇到问题(它是一个杂乱无章的大量模板库,因此可能会有点令人沮丧),您仍然愿意要使用 Python,您可以尝试类似this 或this。 哈,升级! +1 给你。我编译了 PeLib。出于某种奇怪的原因,他们用宏重新定义了“for”。 VS2013 不喜欢那样。无论如何,感谢您的链接。我会给他们一次好一次。即使 PeLib 完成这项工作,其他人将来也可以派上用场。谢谢。 有效!是的,PeLib 是一团糟。他们无缘无故地将事物重新定义为看起来完全相同的值。但是,它有效。它为我列出了所有的 DLL 依赖项,并且在编译后使用起来并不痛苦。谢谢,这将为我节省大量时间。

以上是关于如何以编程方式列出 C++ 或 Python 中的 DLL 依赖项?的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式列出解决方案中的所有项目?

如何以编程方式列出解决方案中的所有项目?

以编程方式递归列出eclipse工作区中的所有文件

包含滤波器系数的 C++ 头文件 (.h) 或 C 中的 .h 文件

Python3:以编程方式列出虚拟环境中所有已安装的包和版本[重复]

如何以编程方式(Python)抓取流式实时股票图表代码数据及其指标