具有 InternalCall 属性的 C# 内部静态外部 - 内部还是外部?

标签 c# .net

another question我问,出现了一条评论,指出 .NET 框架的 Array.Copy 方法使用非托管代码。我去挖 Reflector并发现 Array.Copy 方法重载的签名之一定义如下:

[MethodImpl(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
internal static extern void Copy(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length, bool reliable);

看完之后,我有点懵了。我困惑的根源是 extern 修饰符,这意味着(MSDN 链接):

The extern modifier is used to declare a method that is implemented externally.

但是,方法声明也用 MethodImplOptions.InternalCall 属性修饰,它指示(MSDN 链接):

Specifies an internal call. An internal call is a call to a method that is implemented within the common language runtime itself.

谁能解释这个看似明显的矛盾?

最佳答案

我会评论 leppie's发布,但它变得有点长。

我目前正在研究一个实验性的 CLI 实现。在很多情况下,如果不了解虚拟机内部是如何实现的,就无法实现公开公开的方法(或属性)。一个例子是 OffsetToStringData ,这需要了解内存管理器如何分配字符串。

对于这种没有 C# 代码来表达方法的情况,您可以以一种特殊的方式处理对方法的每次调用内部 JIT 过程。作为此处的示例,在将 call 字节码传递给 native 代码生成器之前,将其替换为 ldc.i4(加载常量整数)。 InternalCall 标志表示“此方法的主体由运行时本身以特殊方式处理”。可能有也可能没有实际的实现——在我的代码中的几种情况下,调用被视为 intrinsic。由 JIT。

在其他情况下,JIT 可能有特殊的可用信息,允许对方法进行大量优化。一个例子是 Math 方法,即使这些 can be implemented in C# , 指定 InternalCall 使它们成为有效的内在函数具有显着的性能优势。

在 C# 中,方法必须有主体,除非它是 abstractexternextern 表示一般“您可以从 C# 代码调用此方法,但它的主体实际上在其他地方定义。”。当 JIT 到达对 extern 方法的调用时,它会查找在哪里可以找到主体并根据结果以不同的方式表现。

  • DllImport 属性指示 JIT 生成 P/Invoke stub 以调用 native 代码实现。
  • InternalCall 标志指示 JIT 以自定义方式处理调用。
  • (还有其他一些,但我没有想出可供使用的示例。)

关于具有 InternalCall 属性的 C# 内部静态外部 - 内部还是外部?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1211462/

相关文章:

使用表单数据的 C# 表单例份验证

c# - WCF 服务 : Dropped connection handling

c# - 关于应用程序在 XP/W2K3 中没有获得焦点的问题

c# - 协方差和 IList

c# - Selenium 不进入网站

c# - Visual Studio c# 相对路径,程序搜索两个路径,即使它找到了正确的路径

c# - 使用 lambda 表达式调用字典的键对象的方法

c# - 如何从对 web 服务的请求中获取客户端 IP 地址

c# - UserControl 绑定(bind)到模型属性

c# - .net 相当于 Delphi QuotedStr 函数