日期:2014-05-18  浏览次数:22560 次

C# 调用C++的DLL 后释放内存?
C#程序调用C++编写的BLL中的方法,怎么是否这过程中占用的内存?是在C#中写,还是在C++的DLL中写?怎么写?

------解决方案--------------------
探讨

如果是stdcall调用,就是由dll释放
如果是cdecl调用,就是谁调用谁释放

------解决方案--------------------
2楼说的正确,这个问题需要比较深入了解,要想成功释放非托管代码分配的内存,必须先确定非托管代码的内存分配方式,才能在互操作是选择正确的方法释放非托管内存,
在非托管代码中,有3种分配方式:

1、C语言:malloc 、free
2、C++:new、delete
3、COM:CoTaskMenAlloc、CoTaskMenFree

第三种方式是互操作默认的释放非托管内存的方法!也就是说,采用前两种方式分配的非托管内存,托管代码不能正确释放,必须由非托管方自己明确释放:
C++:
wchar_t* GetStringNew()
{
int iBufferSize = 128;
wchar_t* pBuffer = new wchar_t[iBufferSize ];
if(NULL != pBuffer)
{
wcscpy_s(pBuffer, iBufferSize/sizeof(wchar_t), L"String from New");
}
return pBuffer;
}

void FreeNewMemory(void* pBuffer)
{
printf("\n%d", pBuffer);
if(NULL != pBuffer)
{
delete pBuffer;
pBuffer = NULL;
}
}

C#:
[DllImport("NativeLib.dll", 
CallingConvention = CallingConvention.Cdecl, 
CharSet = CharSet.Unicode )]
static extern string GetStringNew();
 [DllImport("NativeLib.dll", 
CallingConvention = CallingConvention.Cdecl, 
CharSet = CharSet.Unicode )]
static extern void FreeNewMemory(IntPtr pbuffer);

IntPtr strPtr=GetStringNew();
string str=Marshal.PtrToStringUni(strPtr);
FreeNewMemory(strPtr); //显示调用非托管释放内存函数释放内存,否则内存会泄露