世界上有很多方法.Net库是用本机代码实现的.来自框架本身的标记为[MethodImpl(MethodImplOptions.InternalCall)].来自某个非托管DLL的标记为[DllImport](例如[DllImport("kernel32.dll")]).到目前为止没有什么不寻常的.

但是在写answer for another question的时候,我发现有很多标有[DllImport("QCall")]的方法.它们似乎是.Net(例如GC._Collect())的内部实现.

我的问题是:[DllImport("QCall")]到底是什么意思?[DllImport("QCall")][MethodImpl(MethodImplOptions.InternalCall)]有什么区别?

推荐答案

这是一条旧线.因为CoreCLR现在在GitHub上是开源的;如果有人还在寻找答案,这里是official documentation个:

Calling from managed to native code

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

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

然后在副标题中继续:

举例说明:

.net相关问答推荐

条带连接支付—引发异常

Puppeteer LaunchAsync 在未打开浏览器的情况下挂起

为什么这个同步运行的异步睡眠会挂起?

.NET Async / Await:状态机如何知道何时继续执行?

如何从标头中检索基本身份验证凭据?

C#:内存不足异常

为什么递归调用会导致不同堆栈深度的 StackOverflow?

从 Web.Config 中的邮箱友好显示名称存储 Smtp

在 .NET (C#) 中本地存储数据的最佳方式

String.Format - 它是如何工作的以及如何实现自定义格式字符串

.NET 进程间通信的最佳 Select 是什么?

为什么会出现编译错误使用未分配的局部变量?

如何知道 DateTime 是否在 C# 中的 DateRange 之间

C# 中的 F# List.map 类似功能?

立即检测客户端与服务器套接字的断开连接

使 HashSet 不区分大小写

将 SignalR 2.0 .NET 客户端重新连接到服务器集线器的最佳实践

ADO.NET Entity Framework:更新向导不会添加表

为 webClient.DownloadFile() 设置超时

从 bcp 客户端接收到 colid 6 的无效列长度