每当我深入了解反射器时,我都会碰到没有光源的extern
方法。我在http://msdn.microsoft.com/en-us/library/e59b22c5(v=vs.80).aspx阅读了msdn文档。我从那篇文章得到的是必须注入带有extern
修饰符的方法。我将其解释为意味着它的工作方式类似于抽象工厂模式。我也注意到我从未见过非静态的外部方法。静态声明是一个要求(我可以看到这有什么意义)?我还在猜这里,我不确定它是如何运作的。在我看来,编译器必须识别某些缓解处理的属性,但我不知道除了我遇到的属性之外的属性,如MSDN示例中的MethodImplAttribute
和DllImportAttribute
。有人如何利用extern
属性?它说,在许多情况下,这可以提高性能。另外,我如何查看extern
方法的来源Object.InternalGetEquals()
?
答案 0 :(得分:95)
考虑阅读C#规范的第10.6.7节,它解答了许多问题。为了您的方便,我在这里复制了部分内容:
当方法声明包含时 extern修饰符,那个方法说 成为一种外部方法。外部 方法在外部实施, 通常使用除以外的语言 C#。因为外部方法 声明不提供实际 实现,方法体 外部方法只包含一个 分号。外部方法可能不会 是通用的。外部修饰符是 通常与a结合使用 DllImport属性, 允许外部方法 由DLL实现(动态链接 库)。执行环境 可以支持其他机制 外部方法的实现 可以提供。当一个外部 方法包括DllImport属性, 方法声明也必须 包括一个静态修饰符。
有人如何利用extern属性?
如何查看Object.InternalGetEquals()等外部方法的来源?
答案 1 :(得分:29)
标有extern
[DllImport]
属性的方法通常是对C库的调用。此功能对于调用WinAPI或遗留代码非常有用。
这是来自MSDN的示例:
using System;
using System.Runtime.InteropServices;
class MainClass
{
[DllImport("User32.dll")]
public static extern int MessageBox(int h, string m, string c, int type);
static int Main()
{
string myString;
Console.Write("Enter your message: ");
myString = Console.ReadLine();
return MessageBox(0, myString, "My Message Box", 0);
}
}
它调用MessageBox
,它在Windows user32.dll
库中定义。运行时在这里为您完成所有繁重的工作,尽管有时您需要手动管理内存。如果您的签名错误,您的程序可能会失败,您可能会引入泄漏或方法可能返回完全不同的东西,所以要小心!我发现pinvoke.net是纠正不同API签名的绝佳工具。
.NET Framework中的一些extern
方法没有[DllImport]
属性,但是用[MethodImpl (MethodImplOptions.InternalCall)]
属性修饰,通常是在CLR中实现的,用C语言编写同样。有些此类方法无法在C#中实现,因为它们管理运行时本身,有些是在C中实现的,因为它们的性能至关重要且C更快。
这就是关于他们的MSDN says:
指定内部呼叫。内部调用是对在公共语言运行库本身内实现的方法的调用。
至于查看实际的实现代码,我怀疑你是否可以从Microsoft获得它,但有some cool alternative implementations of CLR around所以一定要检查它们。
答案 2 :(得分:3)
extern
使用平台调用(pinvoke)来促进托管程序集调用非托管代码。 extern
关键字通知编译器它需要生成正确的代码以允许正确的数据封送。
答案 3 :(得分:2)
我们使用" extern"方法声明中的修饰符。它用于指示该方法是在外部实现的。 "的常见用途extern"修饰符具有DllImport属性。使用此属性管理非C#函数调用。 如果您使用的是extern修饰符,则必须包含以下命名空间:
using System.Runtime.InteropServices;
语法类似于:
[DllImport("User32.dll")]
public static extern int MessageBox(int h, string m, string c, int type);