分配和内存使用平台调用非托管code释放(C#) [英] Allocation and deallocation of memory in unmanaged code using platform Invoke (C#)

查看:279
本文介绍了分配和内存使用平台调用非托管code释放(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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆