2011-11-30 117 views
3

我不知道這是不是個好主意。我在C#中使用了非託管DLL(由我編寫)。在非託管DLL中存儲「託管」上下文參數

有一些回調函數可以在DLL中設置,但這些回調函數只能映射到C#端的靜態類成員。

因爲我想對特定的類實例進行回調操作,所以我想知道將類實例指針存儲在DLL的狀態信息中是否安全。

從DLL的角度來看,這將簡單地是一個32位的上下文整數,但是從C#側這將是一個實際的類「指針」或「參考」,用回調簽名定義像這樣:

public delegate void StatusChangeHandler(ContextClass context, int someCallbackValue); 

它編譯,它似乎工作,我只是不知道這是否有保證。這是一種可接受的做法嗎?

+0

mange =寄生蟎引起的持續性皮膚病? – spender

+0

糟糕!錯字現在已更正。 – user1073363

回答

0

我在這裏看到的一個問題是.Net有一個垃圾回收器,它可以移動你的類。所以你保存的指針可能會失效。爲了防止這種情況的簡單類型你應約束這樣的對象:

byte[] b = new byte[1000]; 
// pin b, and get pointer to the first element. 
fixed (byte* ptr = &b) 
{ 
    //use your fixed pointer to b. b will not be moved untill code leaves fixed region. 
} 

雖然,對於複雜的類型,淨可能smartenough自動固定對象,我不會依靠這一點。 所以你寫的東西是這樣的:

var ctx = new Context(); 
fixed (IntPtr ptr = &ctx) 
{ 
    StatusChange(ptr); 
    // do other stuff, and don't leave fixed region, until you can clear the pointer in the native library. 
} 

不過說真的,我覺得一個更簡單和可靠的方式將是創建一個靜態字典的上下文對象,並給您的本機DLL只對字典的關鍵,它可以是數字,字符串或GUID。例如。任何有價值的東西,不是指針。

+0

謝謝,是的,這些也是我的擔憂。我會按照你的建議去使用索引。 – user1073363