C# 调用 C++编译的动态库,内存释放问题

yang_km 2016-09-03 06:16:46
在C++下编译了动态库给C#调用:
C++的代码如下
X264ENCODER_API int _stdcall AvcEncode(char* buf, uint8_t* &outdata, int &outdata_size)
{
unsigned long yuvimg_size = Width * Height * 3 / 2;
int x264buf_len = 0;
unsigned char* yuvbuf = (unsigned char*)malloc(yuvimg_size);
unsigned char* x264buf = (unsigned char*)malloc(yuvimg_size * 10);
char* rgbbuf = buf;
if (rgbbuf)
{
RGB2YUV420((LPBYTE)rgbbuf, Width, Height, (LPBYTE)yuvbuf, &yuvimg_size);
bool is_keyframe = false;
Encode(yuvbuf, x264buf, x264buf_len, is_keyframe);
if (x264buf_len > 0)
{
outdata = (uint8_t*)malloc(x264buf_len);//这里申请未释放,造成内存泄漏
memset(outdata, 0, x264buf_len);
memcpy(outdata, x264buf, x264buf_len);
outdata_size = x264buf_len;
}
}
free(x264buf);
x264buf = NULL;
free(yuvbuf);
yuvbuf = NULL;
return true;
}

C#中调用如下
[DllImport(PATH, CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
[SuppressUnmanagedCodeSecurity]
public static extern int AvcEncode(IntPtr buf, ref IntPtr outdata, ref int outdata_size);


程序运行中进程内存监测,内存占用一直递增

初步判断为动态库中申请的内存未释放造成,这里有什么办法释放吗?在C#中无法直接释放吧?
请教了,谢谢!
...全文
469 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
yang_km 2016-09-06
  • 打赏
  • 举报
回复
首先感谢各位给我的思路,问题已得到解决 我也把解决方案发贴出来,如果各位发现还有问题的地方或者有更好的解决方法,请不吝赐教 C++中代码修改如下
X264ENCODER_API int _stdcall AvcEncode(char* buf, uint8_t* &outdata, int &outdata_size)
{
	unsigned long yuvimg_size = Width * Height * 3 / 2;
	int x264buf_len = 0;
	unsigned char* yuvbuf = (unsigned char*)malloc(yuvimg_size);
	unsigned char* x264buf = (unsigned char*)malloc(yuvimg_size * 10);
	char* rgbbuf = buf;
	if (rgbbuf)
	{
		RGB2YUV420((LPBYTE)rgbbuf, Width, Height, (LPBYTE)yuvbuf, &yuvimg_size);
		bool is_keyframe = false;
		Encode(yuvbuf, x264buf, x264buf_len, is_keyframe);
		if (x264buf_len > 0)
		{
			outdata = (uint8_t*)malloc(x264buf_len);
			memset(outdata, 0, x264buf_len);
			memcpy(outdata, x264buf, x264buf_len);
			buf_temp = outdata;//记录申请地址
			outdata_size = x264buf_len;
		}
	}
	free(x264buf);
	x264buf = NULL;
	free(yuvbuf);
	yuvbuf = NULL;
	return true;
}
下面用于释放内存

X264ENCODER_API void AvcFreeBuf(void)
{
	free(buf_temp);
	buf_temp = NULL;
}
在C#中调用如下

[DllImport(PATH, CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
[SuppressUnmanagedCodeSecurity]
public static extern int AvcEncode(IntPtr buf, ref IntPtr outdata, ref int outdata_size);
[DllImport(PATH, CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
[SuppressUnmanagedCodeSecurity]
public static extern void AvcFreeBuf();
[DllImport("kernel32.dll")]
public static extern void CopyMemory(IntPtr Destination, IntPtr Source, int Length);

IntPtr _data = IntPtr.Zero;
int _size = 0;
int hr = AvcEncode(buf, ref out_buf, ref out_buf_len);
IntPtr buf_temp = Marshal.AllocHGlobal(out_buf_len);//申请临时空间,存放传出的数据
CopyMemory(buf_temp, out_buf, out_buf_len);//源内存块中的数据复制到新地址:buf_temp
AvcFreeBuf();//释放源内存块:调用动态库中的方法,释放它申请的内存
//这里加入你要操作的代码
if (buf_record != IntPtr.Zero)
{//完成操作后,释放临时空间:buf_temp
     Marshal.FreeHGlobal(buf_temp);
     buf_temp = IntPtr.Zero;
}
caojinrong 2016-09-03
  • 打赏
  • 举报
回复
C语言中的malloc、realloc、free对应C#中的 Marshal.AllocCoTaskMem、 Marshal.ReAllocCoTaskMem和 Marshal.FreeCoTaskMem,参考http://www.mono-project.com/docs/advanced/pinvoke/
paschen 2016-09-03
  • 打赏
  • 举报
回复
再提供一个C++版的释放函数,否则C#无法直接调用函数释放 或者统一用API方式申请释放内存
fefe82 2016-09-03
  • 打赏
  • 举报
回复
你用 C++ 再写一个专门用来释放内存的函数给 C# 用

3,881

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧