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

svi*_*ick 67 .net internals dllimport

.Net库中的许多方法都是在本机代码中实现的.那些来自框架本身的标记着[MethodImpl(MethodImplOptions.InternalCall)].来自某些非托管DLL的那些标记有[DllImport](例如[DllImport("kernel32.dll")]).到目前为止没有什

但在为另一个问题答案时,我发现有许多标记的方法[DllImport("QCall")].它们似乎是.Net的内部实现(例如GC._Collect()).

我的问题是:究竟是什么[DllImport("QCall")]意思?[DllImport("QCall")]和之间有什么区别[MethodImpl(MethodImplOptions.InternalCall)]

SLa*_*aks 36

我问.Net团队中的一些人这件事.

QCalls是对CLR运行时内的本机方法的调用.它们的行为与其他[DllImport]s一样,但它们更快,因为它们对本机方法做了特定的(未记录的)假设,因此它们可以跳过各种编组和GC以及异常检查.

InternalCall是不同的; 它用于调用在运行时生成的特殊反射式事物(这不是很清楚).


vul*_*ven 16

这是一种旧思路.因为CoreCLR现在是在GitHub上开源的; 如果有人仍在寻求答案,这里是官方文件:

从托管代码调用本机代码

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

FCall的一个小变体称为HCall(用于Helper调用),用于实现JIT助手,用于访问多维数组元素,范围检查等.HCall和FCall之间的唯一区别是HCall方法不会显示在异常堆栈跟踪中.

然后它继续在小标题中:

举例: