使用平台Invoke(C#)在非托管代码中分配和释放内存),我们从托管代码(C#)调用它们。我不确定下面的代码是否没有内存泄漏?C#代码:[DllImport("SampleDLL.dll")]publicexternvoidgetString([MarshalAs(UnmanagedType.LPStr)]outStringstrbuilder);[DllImport("SampleDLL.dll")]publicexternvoidfreeMemory([MarshalAs(UnmanagedType.LPStr)]outStringstrBuilder);....//调用非托管代码getString(outstr);控制台.WriteLine(str);免费内存(输出海峡);C++代码:externvoid_cdeclgetString(char**str){*str=newchar[20];std::stringtemp="Helloworld";strncpy(*str,temp.c_str(),temp.length()+1);}externvoid_cdeclfreeMemory(char**str){if(*str)delete[]*str;*海峡=空;不,这行不通。pinvoke编组器将尝试使用CoTaskMemFree()释放字符串的内存。它不知道你有释放功能。这不会很好,您没有使用CoTaskMemAlloc分配字符串。这将是XP中的无声内存泄漏,在Vista中是崩溃和上升。你必须阻止编组器做正确的工作:[DllImport("SampleDLL.dll")]publicexternvoidgetString(outIntPtrstrptr);[DllImport("SampleDLL.dll")]publicexternvoidfreeMemory(IntPtrstrptr);然后,需要在C#代码中使用Marshal.PtrToStringAnsi()自己从返回的指针中编组字符串。就我个人而言,我发现使用BSTR最容易做到这一点,无需导出解除分配器。C++BSTRANSItoBSTR(constchar*input){BSTR结果=NULL;intlenA=lstrlenA(输入);intlenW=::MultiByteToWideChar(CP_ACP,0,输入,lenA,NULL,0);如果(lenW>0){结果=::SysAllocStringLen(0,lenW);::MultiByteToWideChar(CP_ACP,0,输入,lenA,结果,lenW);}返回结果;}BSTR__stdcallgetString(){返回ANSItoBSTR("Helloworld");}当然,如果使用Unicode字符串就更容易了。BSTR__stdcallgetString(){return::SysAllocString(L"Helloworld");}C#[DllImport(@"test.dll")][返回:MarshalAs(UnmanagedType.BStr)]privatestaticexternstringgetString();在C#方面就是这样。您只需调用getString()并返回一个.net字符串,您不需要编组任何内容或调用释放器。以上就是C#学习教程:使用平台Invoke(C#)分配和释放非托管代码内存共享的全部内容。如果对你有用,需要了解更多C#学习教程,希望大家多加关注——本文来自网络收藏,不代表立场,如涉及侵权,请点击右边联系管理员删除。如需转载请注明出处:
