我有一個很奇怪的問題:.NET interop中是否有內存安全級別?
我正在測試使用NUnit的非託管C DLL的幾個函數調用。奇怪的是,測試運行正常時會失敗,但是當我使用調試器運行它時(即使沒有中斷點),它也會正常傳輸。
因此,作爲普通的NUnit應用程序,調試器有更廣泛的內存訪問嗎?
我已隔離失敗的通話。它傳遞一個字符串指向一個字符串,編組人員應該將其轉換爲一個C#字符串。 C面看起來是這樣的:
#define get_symbol(a) ((a).a_w.w_symbol->s_name)
EXTERN char *atom_get_symbol(t_atom *a);
...
char *atom_get_symbol(t_atom *a) {
return get_symbol(*a);
}
和C#代碼:
[DllImport("csharp.dll", EntryPoint="atom_get_symbol")]
[return:MarshalAs(UnmanagedType.LPStr)]
private static extern string atom_get_symbol(IntPtr a);
這是從C返回的指針頗深列表的代碼和部分內。那麼我只是錯過了一些安全設置?
編輯:這裏是例外,我得到:
System.AccessViolationException:(翻譯成英文:)有讀取或寫入保護內存的嘗試。這可能表示其他內存已損壞。
at Microsoft.Win32.Win32Native.CoTaskMemFree(IntPtr ptr)
at ....atom_get_symbol(IntPtr a)
SOLUTION:
的問題是,該編組想釋放這是一個C結構的一部分的存儲器中。但它只是前人的精力使字符串的副本,並留下記憶的是:
[DllImport("csharp.dll", EntryPoint="atom_get_symbol")]
private static extern IntPtr atom_get_symbol(IntPtr a);
,然後在代碼中獲取字符串的副本:
var string = Marshal.PtrToStringAnsi(atom_get_symbol(ptrToStruct));
太棒了!
「失敗」是什麼意思? –
我收到一個異常,指出在C#調用atom_get_symbol時嘗試讀取或寫入受保護的內存。我檢查了作爲參數傳遞的IntPtr參數,它有一個有效的值。當我使用相同的IntPtr到列表從C代碼返回一個浮點數時,它工作正常。所以它只有一個問題,當它應該返回一個字符串... – thalm
你如何分配你通過atom_get_symbol從託管代碼傳遞的IntPtr? –