这个 DLL 是托管的还是非托管的?

Posted

技术标签:

【中文标题】这个 DLL 是托管的还是非托管的?【英文标题】:Is this DLL managed or unmanaged? 【发布时间】:2011-07-13 15:45:31 【问题描述】:

我在你面前有一个 DLL。只使用 Win32 SDK,你能告诉我这个 DLL 是不是一个 .NET 程序集吗?

为什么?我们的应用程序以 DLL 的形式加载插件。我们正在尝试扩展这些插件的定义以允许 .NET 程序集,但接口会有所不同,因此加载器在加载之前需要知道 DLL 是托管还是非托管。

【问题讨论】:

您可以要求插件创建者包含一个特殊资源。 【参考方案1】:

我只是尝试将其作为 .NET 程序集加载,如果失败,则退回到“非托管”接口。

【讨论】:

在加载托管程序集时不会加载诸如缺少依赖项之类的错误导致插件加载器不必要地回退到非托管模式吗? @Harindaka:我想会的,那又怎样?非托管加载器也会失败,这将是故事的结局。你觉得这有什么问题?【参考方案2】:

您可以检查 PE 标头信息以了解有关 DLL 中包含的信息类型的信息。这个article describes how to accomplish this in detail。

【讨论】:

所有有用的信息都应该包含在这篇文章中,不仅仅是链接,链接现在已经死了;) @DrCopyPaste web.archive.org/web/20160202125049/http://blogs.msdn.com/b/…【参考方案3】:

要确定 DLL(或 EXE)是托管的还是非托管的,use dumpbin.exe with the /dependents switch。如果您看到 mscoree.dll in the output,则该程序集是托管程序集。

例如,对于我在 Visual Studio 2010 中创建的托管 DLL,我得到以下输出:

Dump of file <MANAGED_DLL>.dll

File Type: DLL

  Image has the following dependencies:

    mscoree.dll

  Summary

        2000 .reloc
        2000 .rsrc
        2000 .sdata
       12000 .text

dumpbin.exe 作为 Visual Studio 工具 的一部分提供。要运行它,一个方便的方法是通过 Visual Studio 命令提示符。例如,在我运行 Visual Studio 2010 的 Windows 7 机器上,我在 Windows 开始菜单中找到了 Visual Studio 命令提示符:

Microsoft Visual Studio 2010 => Visual Studio 工具 => Visual Studio命令提示符 (2010)

然后,在 Visual Studio 命令提示符中输入:

dumpbin /dependents DLL_OF_INTEREST.DLL

dumpbin /dependents EXE_OF_INTEREST.EXE

作为替代方法,您可以使用 Visual Studio 工具中也包含的 corflags.exe 实用程序。在 unmanaged 程序集上从 Visual Studio 命令提示符运行它:

corflags UNMANAGED.DLL

..你会得到:

corflags : error CF008 : The specified file does not have a valid managed header

...而在 托管 程序集上,您会得到如下内容:

Version   : v2.0.50727
CLR Header: 2.5
PE        : PE32
CorFlags  : 1
ILONLY    : 1
32BIT     : 0
Signed    : 0

相关:

How to determine if a .NET assembly was built for x86 or x64?,和 How can I detect the type of a dll? (COM, .NET, WIN32)。

【讨论】:

对于找不到 dumpbin.exe 的任何人,它包含在 MSVC C++ 构建工具中(例如 MSVC v142 - VS 2019 C++ x64/x86 build tools)。

以上是关于这个 DLL 是托管的还是非托管的?的主要内容,如果未能解决你的问题,请参考以下文章

检查非托管 DLL 是 32 位还是 64 位?

将非托管 C++ dll 添加到托管 C++ dll

从非托管 dll 文件(注入到正在运行的进程中)调用托管 dll

几个appdomains调用相同的非托管DLL

桥接非托管类和托管类

如何使用CString参考调用非托管C ++ DLL