带有InternalCall属性的C#内部静态外部

在我问的另一个问题中,出现了一条评论,指出.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链接):

extern修饰符用于声明外部实现的方法。

但是,方法声明也使用MethodImplOptions.InternalCall属性进行了修饰,该属性表示(MSDN链接):

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

任何人都可以解释这个看似明显的矛盾吗?


我只是会对leppie的帖子发表评论,但它会变得有点长。

我目前正在开发一个实验性的CLI实现。 在很多情况下,如果没有关于虚拟机如何在内部实现的知识,公开暴露的方法(或属性)就无法实现。 OffsetToStringData就是一个例子,它需要知道内存管理器如何分配字符串。

对于这样的情况,如果没有C#代码来表示该方法,则可以用JIT进程内部的特殊方式来对待每个对该方法的调用。 作为一个例子,在将它传递给本地代码生成器之前,用ldc.i4 (加载常量整数)来替换call字节代码。 InternalCall标志表示“该方法的主体由运行时本身以特殊方式处理”。 可能有也可能没有实际的实现 - 在我的代码中的几个例子中,调用被JIT视为内在。

还有其他一些情况下,JIT可能有特殊的信息可以对方法进行大量的优化。 一个例子是Math方法,尽管这些方法可以在C#中实现,但指定InternalCall以使它们有效地实现内部函数具有显着的性能优势。

在C#中,一个方法必须有一个主体,除非它是abstractexternextern意味着一个通用的“你可以从C#代码中调用这个方法,但它的主体实际上是在别处定义的。” 当JIT到达一个extern方法的调用时,它会查找在哪里找到主体,并根据结果以不同的方式运行。

  • DllImport属性指示JIT使P / Invoke存根调用本地代码实现。
  • InternalCall标志指示JIT以自定义的方式处理该呼叫。
  • (还有一些其他的,但我没有例外的例子,供他们使用。)

  • InternalCall是由框架提供的。

    extern说你不提供代码。

    extern可以用于2个一般情况,比如上面,或者用p / invoke。

    使用p / invoke,你只需告诉方法在哪里得到实现。

    链接地址: http://www.djcxy.com/p/82147.html

    上一篇: C# internal static extern with InternalCall attribute

    下一篇: Understanding IoC Containers and Dependency Injection