我正在查看System.buffer.cs on the Microsoft reference source,我看到此代码从第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()
函数。该功能在哪里实施?
答案 0 :(得分:2)
在我阅读了 Ben Voigt 在评论中发布的问题和答案之后:
如何在C#中实现Array.Copy? [Hans Passant的回答]
https://stackoverflow.com/a/6558515/103167
我搜索了JitHelpers.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。与FCalls不同,QCalls会将所有参数编组为非托管类型,如普通的P / Invoke。 QCall也像普通的P / Invoke一样切换到抢占式GC模式。与FCall相比,这两个特性应该使QCall更容易可靠地写入。 QCalls不容易出现GC漏洞常见的GC漏洞和GC饥饿错误。
如果您运行ILDasm(一条可能的路径:C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7 Tools\x64\ildasm.exe
)并打开 mscorlib.dll (一条可能的路径:C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll
),并查看{ {1}}> System
,您会看到System.Buffer
,Memmove
和_Memmove
。