核心库中"_Memmove"代码的实现在哪里



我正在Microsoft引用源上查看System.buffer.cs,我看到从第508行开始的代码:

#if WIN64
private unsafe static void _Memmove(byte* dest, byte* src, ulong len)
#else
private unsafe static void _Memmove(byte* dest, byte* src, uint len)
#endif
{
__Memmove(dest, src, len);
}
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
[SecurityCritical]
[ResourceExposure(ResourceScope.None)]        
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
#if WIN64
extern private unsafe static void __Memmove(byte* dest, byte* src, ulong len);
#else
extern private unsafe static void __Memmove(byte* dest, byte* src, uint len);
#endif

该代码引用外部__Memmove()函数。该功能在哪里实现?

在我阅读了Ben Voigt在评论中发布的问题和答案之后:

Array.Copy 是如何在 C# 中实现的?[汉斯·帕桑特的回答]
https://stackoverflow.com/a/6558515/103167

我搜索了JitHelpers.QCall并找到了这篇文章:

什么是 [DllImport("QCall")]?

这把我带到了这个页面:

coreclr/Documentation/mscorlib.md - 从托管代码调用到本机代码
https://github.com/dotnet/coreclr/blob/0c88c2e67260ddcb1d400eb6adda19de627998f5/Documentation/mscorlib.md#calling-from-managed-to-native-code

我们有两种从托管代码调用 CLR 的技术。FCall 允许您直接调用 CLR 代码,并在操作对象方面提供了很大的灵活性,尽管由于未正确跟踪对象引用很容易导致 GC 漏洞。QCall 允许您通过 P/Invoke 调用 CLR,并且比 FCall 更难意外误用。FCall 在托管代码中标识为 extern 方法,并设置了 MethodImplOptions.InternalCall 位。QCalls是静态的外部方法,看起来像常规的P/Invokes,但属于一个名为"QCall"的库。

[...]

QCall 功能行为
QCalls 非常像从mscorlib.dll到 CLR 的普通 P/Invoke。与 FCall 不同,QCalls 会将所有参数封送为非托管类型,如普通的 P/Invoke。QCall 还可以像普通的 P/Invoke 一样切换到抢占式 GC 模式。与FCalls相比,这两个功能应该使QCalls更容易可靠地编写。QCall不容易出现FCall常见的GC孔和GC饥饿错误。

如果您运行 ILDasm(一种可能的路径:C:Program Files (x86)Microsoft SDKsWindowsv10.0AbinNETFX 4.7 Toolsx64ildasm.exe)并打开mscorlib.dll(一种可能的路径:C:WindowsMicrosoft.NETFrameworkv4.0.30319mscorlib.dll),并在System>System.Buffer下查看,您将看到Memmove_Memmove__Memmove

最新更新