2016年10月18日 星期二

c#中使用指標

C#中要使用指標
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

沒有留言:

張貼留言