托管代碼 (managed code):由公共語言運行庫環境(而不是直接由操作系統)執行的代碼。托管代碼應用程序可以獲得公共語言運行庫服務,例如自動
垃圾回收、運行庫類型檢查和安全支持等。這些服務幫助提供獨立於平台和語言的、統一的托管代碼應用程序行為。 非托管代碼(Unmanaged Code):在公共語言運行庫環境的外部,由操作系統直接執行的代碼。非托管代碼必須提供自己的垃圾回收、類型檢查、安全支
持等服務;它與托管代碼不同,後者從公共語言運行庫中獲得這些服務。
Unsafe的代碼介於這兩者之間,它也是在CLR的環境中執行,但是我們可以直接操作內存。只要我們的代碼包含下面三個指針操作符之一就需要使用Unsafe
關鍵字:
*
&
->
例如:
unsafe static void ChangeValue(int* pInt) { *pInt = 23; }
上面的代碼由於是在CLR下托管執行,為了減少內存碎片C#的自動垃圾回收機制會允許已經分配的內存在運行時進行位置調整,所以如果我們多次調用的話就可能
導致指針指向其他的變量。比如*pInt為
指向一個變量的地址為1001,CLR在重新內存整理分配後該變量就存儲在地址為5001的地方。而原來1001的地方可能會
被分配其他變量,要解決這個問題我們就需要使用Fixed關鍵字。
fixed 語句禁止垃圾回收器重定位可移動的變量。fixed 語句只能出現在不安全的上下文中。Fixed 還可用於創建固定大小的緩沖區。如下面例子:
using System; class CaryData { public int data; } class CProgram { unsafe static void ChangeValue(int* pInt) { *pInt = 23; } public unsafe static void Main() { CaryData cd = new CaryData(); Console.WriteLine("改變前: {0}", cd.data); fixed (int* p = &cd.data) { ChangeValue(p); } Console.WriteLine("改變後: {0}", cd.data); } }
注意要勾選項目屬性中生成標簽的允許不安全代碼。