.NET9托管如何到非托管的?

点击上方蓝字 江湖评谈设为关注/星标

380d121fb643ff260d70faaa3b44e8a0.png

前言

.NET代码全部都是托管的,托管在了CLR这个运行时上面。但是实际上真正的运行得靠非托管,计算机它不识别MSIL的二进制(参考:罕见的技术:MSIL的机器码简析)。有没有想过如何从托管到非托管呢?本篇看下

详情

简单的例子:

static Main(string[] args)
  {
     GC.Collect();
  }

托管意即C#代码,非托管意即C/C++/ASM代码。这里以GC垃圾回收GC.Collect()为例,Collect函数毫无疑问是托管的。当你对Collect跟踪到时候,JIT会把整个MSIL加载到内存里面去,然后通过DebugInfo调试信息表定位当前断点的位置以及当前光标所在的位置。准确的让调试器停下来或者继续运行。

既然加载到内存,其实就很好理解了。Debug模式下通过DebugInfo来确定当前运行的堆栈轨迹,Release模式下其实也有调试信息,只不过删繁就简了。同样的通过DebugInfo来确定堆栈的运行轨迹。

代码:

extern "C" void QCALLTYPE GCInterface_Collect(INT32 generation, INT32 mode)
{
    QCALL_CONTRACT;
    BEGIN_QCALL;
    _ASSERTE(generation >= -1);
    GCX_COOP();
    GCHeapUtilities::GetGCHeap()->GarbageCollect(generation, false, mode);


    END_QCALL;
}

GC.Collect通过QCall的模式进入到非托管之后,会调用C++代码,进行全代(如果Collect不指定某个代,就会对所有代进行GC)垃圾回收。一段托管代码/函数对应一个非托管的调用约定,双方约定俗成了如何进行通讯/调用的。

整体

整体性来说,Collect托管函数会被CLR加载,然后调用JIT进行Compile。最终Compile的结果里面包含了对于GCInterface_Collect非托管函数FCall的约定调用。如此基本上构成了托管-》非托管的运作过程。

往期精彩回顾

.NET9 Pre3 CLR的优化细节

.NET9 GC标记原理(超核技术)

.NET9异常(CLR)原理(顶阶技术)

ae145e83aa4034bfd4ff4b2bd5323c80.jpeg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值