我在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