extern如何在C#中工作?

每当我对reflection镜看得足够深的时候,我都碰到没有源的extern方法。 我阅读了msdn文档http://msdn.microsoft.com/en-us/library/e59b22c5(v=vs.80).aspx 。 我从那篇文章中得到的是,带有extern修饰符的方法必须被注入。 我将其解释为意味着它像抽象工厂模式那样工作。 我也注意到,我从来没有见过一个非静态的extern方法。 静态声明的一个要求(我可以看到这是如何有意义的)? 我仍然在这里猜测,我不知道它是如何工作的。 在我看来,编译器必须识别某些缓解处理的属性,但我不知道除DllImportAttribute示例中的MethodImplAttributeDllImportAttribute之外的其他属性。 某人如何利用extern属性? 它说在很多情况下这可以提高性能。 另外,我将如何去寻找像Object.InternalGetEquals()extern方法的源?

考虑阅读C#规范的第10.6.7节,它回答了你的许多问题。 为了您的方便,我在这里复制了一部分内容:


当一个方法声明包含一个extern修饰符时,该方法被认为是一个外部方法。 外部方法在外部实现,通常使用C#以外的语言。 由于外部方法声明不提供实际的实现,所以外部方法的方法体只是由分号组成。 外部方法可能不是通用的。 extern修饰符通常与DllImport属性结合使用,允许通过DLL(dynamic链接库)实现外部方法。 执行环境可以支持可以提供外部方法的实现的其他机制。 当外部方法包含DllImport属性时,方法声明还必须包含一个静态修饰符。


某人如何利用extern属性?

  • 用您select的非托pipe语言编写您的代码。
  • 编译成一个DLL,导出你的代码的入口点。
  • build立一个互操作的库,在给定的DLL中将该方法定义为extern方法。
  • 从C#调用它。
  • 利润!

我将如何去寻找像Object.InternalGetEquals()的extern方法的源?

转到https://github.com/dotnet/coreclr/tree/master/src/vm

[DllImport]属性标记extern方法通常是对C库的调用。 此function对于调用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); } } 

它调用Windows user32.dll库中定义的MessageBox 。 运行时为您做了所有繁重的工作,虽然有时您需要手动pipe理内存。 如果你的签名不对,你的程序可能会在通话失败,你可能会引入泄漏或方法可能会返回完全不同的东西,所以要小心! 我发现pinvoke.net是一个很好的工具来纠正不同的API的签名。

.NET Framework中的某些extern方法没有[DllImport]属性,但用[MethodImpl (MethodImplOptions.InternalCall)] [DllImport]属性修饰,通常是CLR本身实现的,也是用C编写的。 有些这样的方法不能在C#中实现,因为它们自己pipe理运行时,有些是用C实现的,因为它们的性能是关键的,C是更快的。

这是MSDN对他们所说的 :

指定一个内部呼叫。 内部调用是对公共语言运行时本身实现的方法的调用。

至于看实际的实现代码,我怀疑你可以从微软得到它,但有一些很酷的替代CLR的实现,所以一定要检查出来。

extern使用平台调用(pinvoke)来方便托pipe程序集调用非托pipe代码。 extern关键字通知编译器,它将需要生成正确的代码以允许正确的数据封送。

我们在方法声明中使用“extern”修饰符。 它用来表示该方法在外部实现。 “extern”修饰符的常见用法是使用DllImport属性。 非C#函数调用使用此属性进行pipe理。 如果您使用的是extern修饰符,那么您必须包含以下命名空间:

using System.Runtime.InteropServices;

语法如下:

[DllImport("User32.dll")] public static extern int MessageBox(int h, string m, string c, int type);