我在C++端有CString cs,在C#端有IntPtr ip,它通過編組機制包含cs的值。如何(如果需要)釋放動態內存時編組CString從C++到C#?
然後,我只需要字符串作爲Marshal.PtrToStringAnsi(IP)和一切工作正常,但我想知道如果我應該如果應該如何刪除非佔用IP的非託管內存,即CS?
我在C++端有CString cs,在C#端有IntPtr ip,它通過編組機制包含cs的值。如何(如果需要)釋放動態內存時編組CString從C++到C#?
然後,我只需要字符串作爲Marshal.PtrToStringAnsi(IP)和一切工作正常,但我想知道如果我應該如果應該如何刪除非佔用IP的非託管內存,即CS?
你不能,你不知道使用了什麼分配器由非託管代碼來創建CString的實例。而且,你必須調用CString析構函數,你不能得到它的地址。
如果此CString對象作爲從C#調用的C++函數的函數返回值返回,那麼您就死在水中了。你的問題並不清楚。你將有一個無法控制的內存泄漏。用C++/CLI編寫的包裝將需要解決這個問題。作爲函數返回值返回的字符串必須由CoTaskMemAlloc()分配,以便由P/Invoke編組人員正確清理。沒有任何C++代碼可以做到這一點。
由非託管代碼分配的非託管內存只能由非託管代碼釋放。所以你需要添加另一個非託管函數,它將獲取指向分配的字符串的指針並釋放內存。這個函數應該在託管代碼完成字符串處理後再調用。
例子:
class Program
{
[DllImport("test.dll")]
static extern IntPtr GetString();
[DllImport("test.dll")]
static extern IntPtr FreeString(IntPtr ptr);
static void Main()
{
IntPtr ptr = GetString();
try
{
var str = Marshal.PtrToStringAnsi(ptr);
// work with the string
}
finally
{
if (ptr != IntPtr.Zero)
{
FreeString(ptr);
}
}
}
}
所以,你是說在C++一側的功能應該是這樣的: CString的FreeString(CString的CS){...} 如果這是這個功能應該如何實現的呢? – 2010-04-28 15:14:10
不,它應該看起來像'void FreeString(CString cs)'。就實現而言,也許一些C++專家可以給他兩分錢。 – 2010-04-28 15:16:43