1. project的build要開啟allow unsafe code (用/unsafe編譯)
2. 指標只能出現在 unsafe{} 區段
這次因為是從其他地方來的byte[],而且陣列很巨大,因此應該要避免資料的複製。
GCHandle pinnedArray = GCHandle.Alloc(byteArray, GCHandleType.Pinned);
IntPtr pointer = pinnedArray.AddrOfPinnedObject();
// Do your stuff...
pinnedArray.Free();
等效於
unsafe{
fixed(byte * p = sourceBuffer){
Intptr ptr = (Intptr)p;
/*...<
DoSomething(ptr);
...*/
}
}
但後面的方法不需要使用unsafe code
在fixed的區段中Managed Object sourceBuffer的記憶體位置會被固定,不受記憶體回收機制的影嚮。若不在fixed 中,Managed Object的位置是沒有意義的。也就是說DoSomething必須在fixed{}結束後不再使用ptr,否則因為ptr實際上已經被釋放,電腦可能發生任何非預期行為。
另外,因為fixed會影響記憶體回收,因此fixed的區段要盡量短。
比較慢但是安全的方法可以用
IntPtr unmanagedPointer = Marshal.AllocHGlobal(bytes.Length);
Marshal.Copy(bytes, 0, unmanagedPointer, bytes.Length);
// Call unmanaged code
Marshal.FreeHGlobal(unmanagedPointer);
但這個方法在Mashal.Copy需耗費較多時間
參考資料: http://stackoverflow.com/questions/537573/how-to-get-intptr-from-byte-in-c-sharp
沒有留言:
張貼留言