为啥要使用 DllImport 属性来代替添加引用?

Posted

技术标签:

【中文标题】为啥要使用 DllImport 属性来代替添加引用?【英文标题】:Why use DllImport Attribute as apposed to adding a reference?为什么要使用 DllImport 属性来代替添加引用? 【发布时间】:2011-03-20 07:33:09 【问题描述】:

我见过几个这样的例子:

[DllImport("user32.dll")]
static extern bool TranslateMessage([In] ref Message lpMsg);

[DllImport("user32.dll")]
static extern IntPtr DispatchMessage([In] ref Message lpmsg);

但是,我不明白为什么有人会这样做,而不是像引用其他库一样仅引用 DLL? MSDN 声明:“在托管应用程序中重用现有非托管代码时,DllImport 属性非常有用。例如,您的托管应用程序可能需要调用非托管 WIN32 API。”但是,这是说引用非托管 dll 没有用还是不可能?

【问题讨论】:

【参考方案1】:

“但是,这样说没有用吗? 引用非托管 dll 或 否则不可能?”

是的,正是如此。您所认为的“引用 DLL”实际上是“引用 .NET 程序集”——碰巧的是,打包人们倾向于引用的程序集的最常见方法是在 DLL 中。

DLLImport 完全是关于导入“传统 DLL”——即使用原始 Windows DLL 导出机制导出所有方法的那些。

将 DLLImport 视为实际上称为“UnmanagedImport”,事情可能会更清楚。

【讨论】:

【参考方案2】:

某些库(例如 user32.dll)是非托管代码。基本上,这意味着他们没有必要的元数据来允许 .Net 通过引用与他们交谈(其中还有很多内容,但希望这能给您足够的先机。)

Using the DllImport Attribute DllImportAttribute Win32/COM PInvoke.Net Managed vs. Unmanaged Development

【讨论】:

【参考方案3】:

简而言之:

添加引用用于:包含托管代码

的DLL文件

DllImport 用于:包含非托管代码

的 DLL 文件

定义:

托管代码仅在公共语言运行时 (CLR) 虚拟机的管理下运行的代码,通常是 .NET Framework(或 Mono) .

非托管代码:任何直接在操作系统上运行的编译二进制文件;使用比 Visual Studio .NET 2002 更早的版本编译的 DLL。

更多详情:Managed, Unmanaged, Native: What Kind of Code Is This?

【讨论】:

我再次投了赞成票,因为这很好地解释了这一点。投反对票太粗鲁了。它应该被禁止 @Fandango68 我同意你的看法——这是一个很好的解释,我也投了赞成票。不知道为什么有人投了反对票。不过,不确定您所说的“它应该被禁止”是什么意思。 @EJoshuaS 在 SO 中的反对意见是行不通的。这就像因为一个简单的错误或误解而抹黑某人。这就是为什么 Facebook 永远不会带来“大拇指”的原因。【参考方案4】:

.NET 平台代码编译为托管代码并使用程序集存储,此程序集是 .DLL 文件,但并非所有 .DLL 文件都是包含托管代码的程序集。 您只能使用“添加引用”样式的托管代码。

其他语言和开发技术使用非托管代码生成 .DLL 文件,实际上您甚至可以与它们进行互操作(调用方法),但您需要 DLLImport 属性

【讨论】:

以上是关于为啥要使用 DllImport 属性来代替添加引用?的主要内容,如果未能解决你的问题,请参考以下文章

如何引用dll文件?

C#的Dllimport能不能调用指定路径的dll文件?

c# dllimport怎么弱引用

为啥要用dbus,如果不用dbus要用啥来代替?

C#中想用messageBox这个类,为啥要添加引用才能使用求解答

为啥要使用引用来获取 *char?当我们使用指针时不使用引用不是更好吗?