分配和内存使用平台调用非托管code释放(C#) [英] Allocation and deallocation of memory in unmanaged code using platform Invoke (C#)
问题描述
我想分配和释放内存在非托管code(C ++),我们称它们从托管code(C#)功能。 荫不知道下面的code是否良好,没有内存泄漏,或不?
C#code:
[的DllImport(SampleDLL.dll)
公众的extern无效的getString([的MarshalAs(UnmanagedType.LPStr)出字符串strbuilder);
[的DllImport(SampleDLL.dll)]
公众的extern无效freeMemory([的MarshalAs(UnmanagedType.LPStr)出字符串strBuilder);
....
//调用非托管code
GetString的(出STR);
Console.WriteLine(STR);
freeMemory(出STR);
C ++ code:
的extern无效_cdecl的getString(字符**海峡)
{
*海峡=新的字符[20];
标准::字符串TEMP =世界,你好;
的strncpy(*海峡,temp.c_str(),temp.length()+ 1);
}
为extern无效_cdecl freeMemory(字符**海峡)
{
如果(* STR)
删除[] *海峡;
*海峡= NULL;
}
没有,这可不行。该PInvoke的编组将会尝试释放内存的字符串CoTaskMemFree()。它不以其他方式知道你有一个释放的功能。这不会很好地工作,你没有分配字符串CoTaskMemAlloc来。这将是在XP无声的内存泄漏,在Vista和一个崩溃。
您必须去尝试做正确的工作停止编组:
[的DllImport(SampleDLL.dll)
公众的extern无效的getString(出IntPtr的strptr);
[的DllImport(SampleDLL.dll)]
公众的extern无效freeMemory(IntPtr的strptr);
然后需要Marshal.PtrToStringAnsi()在C#code,以自己从返回的指针封送字符串。
I want to allocate and deallocate memory in unmanaged code (C++) and we call them functions from managed code (C#). Iam not sure whether the following code is fine without memory leaks or not?
C# code:
[DllImport("SampleDLL.dll")]
public extern void getString([MarshalAs(UnmanagedType.LPStr)] out String strbuilder);
[DllImport("SampleDLL.dll")]
public extern void freeMemory([MarshalAs(UnmanagedType.LPStr)] out String strBuilder);
....
//call to unmanaged code
getString(out str);
Console.WriteLine(str);
freeMemory(out str);
C++ code:
extern void _cdecl getString(char **str)
{
*str = new char[20];
std::string temp = "Hello world";
strncpy(*str,temp.c_str(),temp.length()+1);
}
extern void _cdecl freeMemory(char **str)
{
if(*str)
delete []*str;
*str=NULL;
}
No, this cannot work. The pinvoke marshaller is going to try to release the memory for the string with CoTaskMemFree(). It doesn't otherwise know that you have a release function. That's not going to work well, you didn't allocate the string with CoTaskMemAlloc. This is going to be a silent memory leak in XP, a crash in Vista and up.
You have to stop the marshaller from trying to do the right job:
[DllImport("SampleDLL.dll")]
public extern void getString(out IntPtr strptr);
[DllImport("SampleDLL.dll")]
public extern void freeMemory(IntPtr strptr);
Which then requires Marshal.PtrToStringAnsi() in your C# code to marshal the string yourself from the returned pointer.
这篇关于分配和内存使用平台调用非托管code释放(C#)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!