點選上方 藍字 江湖評談 設為關註/星標
前言
.NET程式碼全部都是托管的,托管在了CLR這個執行時上面。但是實際上真正的執行得靠非托管,電腦它不辨識MSIL的二進制(參考: )。有沒有想過如何從托管到非托管呢?本篇看下
詳情
簡單的例子:
staticMain(string[] args)
{
GC.Collect();
}
托管 意即C#程式碼,非托管意即C / C++/AS M 代 碼。 這裏以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的約定呼叫。如此基本上構成了托管-】非托管的運作過程。
往期精彩回顧