C#调用C++的DLL,二级指针释放的问题。

Jeremy__Liu 2014-12-04 11:10:02
C++中的一个二级指针(unsigned char**) 传入C#中,怎么在C#中释放这个二级指针?C#中用的 ref IntPtr类型与unsigned char**对应。
我是在C++中写了一个释放内存的导出函数,C#中调用这个函数来释放内存,但是好像释放的不干净,如下:
void releasememory(unsigned char** p)
{
if(*p != NULL)
{
delete[] *p;
*p = NULL;
}
}
...全文
560 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
Jeremy__Liu 2014-12-09
  • 打赏
  • 举报
回复
结贴 散分 内存泄露可能出在其他地方
Jeremy__Liu 2014-12-08
  • 打赏
  • 举报
回复
引用 17 楼 wy24789 的回复:
弱弱的问一句怎么知道有内存泄露
打开任务管理器,找到你软件的进程,就能看到内存的占用了。
Saleayas 2014-12-05
  • 打赏
  • 举报
回复
extern "C" __declspec(dllexport) bool GetFrame(unsigned char **ppData)
{
	*ppData = new unsigned char[1000];
	for (int i = 0; i < 1000; ++i)
	{
		(*ppData)[i] = i;
	}
	return true;
}

extern "C" __declspec(dllexport) void ReleaseFrame(unsigned char **ppData)
{
	delete[] *ppData;
	*ppData = NULL;
}
		[DllImport(dllPath, EntryPoint = "GetFrame", CallingConvention = CallingConvention.Cdecl)]
		private static extern void GetFrame_([Out] out IntPtr data);
		public static IntPtr GetFrame()
		{
			IntPtr ptr;
			GetFrame_(out ptr);
			return ptr;
		}

		[DllImport(dllPath, EntryPoint = "ReleaseFrame", CallingConvention = CallingConvention.Cdecl)]
		private static extern void ReleaseFrame_([In] ref IntPtr data);
		public static void ReleaseFrame(IntPtr ptr)
		{
			ReleaseFrame_(ref ptr);
		}
Jeremy__Liu 2014-12-05
  • 打赏
  • 举报
回复
引用 7 楼 tgh1981 的回复:
一说是直接用 Dispose 释放 一说是在c或c++中显式释放 我都晕了
Dispose 怎么释放嘛?
Jeremy__Liu 2014-12-05
  • 打赏
  • 举报
回复
引用 8 楼 Saleayas 的回复:
那我估计是你的 获取这个指针的过程有错误。 你贴出来看看。
[DllImport("VideoCondense.dll", EntryPoint = "GetOneFrame", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern bool GetOneFrame(ref IntPtr pRGBData); 这是在C#中引入DLL的说明 public bool GetFrame(IntPtr prgbdata) { try { if (GetOneFrame(ref prgbdata)) { if (prgbdata != IntPtr.Zero) { pRGBData = prgbdata; return true; } else { nErrorCode = nerrorcode; return false; } } else { nErrorCode = nerrorcode; return false; } } catch (Exception eGetFrame) { return false; } } 之后我调用releasememory接口释放这个pRGBData指针
Saleayas 2014-12-05
  • 打赏
  • 举报
回复
那我估计是你的 获取这个指针的过程有错误。 你贴出来看看。
钛元素 2014-12-05
  • 打赏
  • 举报
回复
一说是直接用 Dispose 释放 一说是在c或c++中显式释放 我都晕了
Jeremy__Liu 2014-12-05
  • 打赏
  • 举报
回复
自己顶一下,问题还没解决
wy24789 2014-12-05
  • 打赏
  • 举报
回复
弱弱的问一句怎么知道有内存泄露
Jeremy__Liu 2014-12-05
  • 打赏
  • 举报
回复
引用 11 楼 Saleayas 的回复:
extern "C" __declspec(dllexport) bool GetFrame(unsigned char **ppData)
{
	*ppData = new unsigned char[1000];
	for (int i = 0; i < 1000; ++i)
	{
		(*ppData)[i] = i;
	}
	return true;
}

extern "C" __declspec(dllexport) void ReleaseFrame(unsigned char **ppData)
{
	delete[] *ppData;
	*ppData = NULL;
}
		[DllImport(dllPath, EntryPoint = "GetFrame", CallingConvention = CallingConvention.Cdecl)]
		private static extern void GetFrame_([Out] out IntPtr data);
		public static IntPtr GetFrame()
		{
			IntPtr ptr;
			GetFrame_(out ptr);
			return ptr;
		}

		[DllImport(dllPath, EntryPoint = "ReleaseFrame", CallingConvention = CallingConvention.Cdecl)]
		private static extern void ReleaseFrame_([In] ref IntPtr data);
		public static void ReleaseFrame(IntPtr ptr)
		{
			ReleaseFrame_(ref ptr);
		}
按照你这个写了,还是有内存泄露。多谢你的回复
Jeremy__Liu 2014-12-05
  • 打赏
  • 举报
回复
引用 11 楼 Saleayas 的回复:
extern "C" __declspec(dllexport) bool GetFrame(unsigned char **ppData)
{
	*ppData = new unsigned char[1000];
	for (int i = 0; i < 1000; ++i)
	{
		(*ppData)[i] = i;
	}
	return true;
}

extern "C" __declspec(dllexport) void ReleaseFrame(unsigned char **ppData)
{
	delete[] *ppData;
	*ppData = NULL;
}
		[DllImport(dllPath, EntryPoint = "GetFrame", CallingConvention = CallingConvention.Cdecl)]
		private static extern void GetFrame_([Out] out IntPtr data);
		public static IntPtr GetFrame()
		{
			IntPtr ptr;
			GetFrame_(out ptr);
			return ptr;
		}

		[DllImport(dllPath, EntryPoint = "ReleaseFrame", CallingConvention = CallingConvention.Cdecl)]
		private static extern void ReleaseFrame_([In] ref IntPtr data);
		public static void ReleaseFrame(IntPtr ptr)
		{
			ReleaseFrame_(ref ptr);
		}
按照你这个写了,还是有内存泄露。多谢你的回复
Jeremy__Liu 2014-12-05
  • 打赏
  • 举报
回复
引用 11 楼 Saleayas 的回复:
extern "C" __declspec(dllexport) bool GetFrame(unsigned char **ppData)
{
	*ppData = new unsigned char[1000];
	for (int i = 0; i < 1000; ++i)
	{
		(*ppData)[i] = i;
	}
	return true;
}

extern "C" __declspec(dllexport) void ReleaseFrame(unsigned char **ppData)
{
	delete[] *ppData;
	*ppData = NULL;
}
		[DllImport(dllPath, EntryPoint = "GetFrame", CallingConvention = CallingConvention.Cdecl)]
		private static extern void GetFrame_([Out] out IntPtr data);
		public static IntPtr GetFrame()
		{
			IntPtr ptr;
			GetFrame_(out ptr);
			return ptr;
		}

		[DllImport(dllPath, EntryPoint = "ReleaseFrame", CallingConvention = CallingConvention.Cdecl)]
		private static extern void ReleaseFrame_([In] ref IntPtr data);
		public static void ReleaseFrame(IntPtr ptr)
		{
			ReleaseFrame_(ref ptr);
		}
按照你这个写了,还是有内存泄露。多谢你的回复
bigbaldy 2014-12-05
  • 打赏
  • 举报
回复
首先你要保证C中调用这个能释放干净,只要C中可以,C#绝对可以
layershow 2014-12-05
  • 打赏
  • 举报
回复
看你的情况都是自己写的函数也不一定非要定义成 char ** 吧 Marshal.AllocHGlobal(1024); Marshal.FreeHGlobal(p); 另外必要情况可以考虑 unsafe 指针
Saleayas 2014-12-04
  • 打赏
  • 举报
回复
不要说在 C# 中,你必须先知道就是在 C 中怎么释放这个指针。 哪怕同样是 C 的非托管内存, new 或 malloc 之类的编译器的内存函数都是不能跨模块的。
Jeremy__Liu 2014-12-04
  • 打赏
  • 举报
回复
引用 3 楼 Saleayas 的回复:
不是这样的,我说不能是指 不可以再一个模块里面使用 new、malloc 来申请内存,而在另外一个模块中来释放之。 如果需要这样,必须使用系统的方法,因为这些方法在不同模块中是一致的。 如果在你 C 模块里面使用了 new 或者 malloc 之类的,那么必须在同样模块中 delete 或者 free 。因为这些函数是基于编译器的。 如果你能保证此时两个模块的编译环境一致,其实也是可以得。 所以,你需要知道具体这个指针在 C 模块中是怎么释放的?
在C++中是这样的定义的:unsigned char** pdata 使用的时候是这样的:*pdata=new unsigned char[10000]; memcpy(*pdata,data,10000); 然后这个指针就传到C#中了。 我是在C++中写的上面的释放函数来释放这个指针的,但是好像释放的不干净,你看看哪里有错误。
Saleayas 2014-12-04
  • 打赏
  • 举报
回复
不是这样的,我说不能是指 不可以再一个模块里面使用 new、malloc 来申请内存,而在另外一个模块中来释放之。 如果需要这样,必须使用系统的方法,因为这些方法在不同模块中是一致的。 如果在你 C 模块里面使用了 new 或者 malloc 之类的,那么必须在同样模块中 delete 或者 free 。因为这些函数是基于编译器的。 如果你能保证此时两个模块的编译环境一致,其实也是可以得。 所以,你需要知道具体这个指针在 C 模块中是怎么释放的?
Jeremy__Liu 2014-12-04
  • 打赏
  • 举报
回复
引用 1 楼 Saleayas 的回复:
不要说在 C# 中,你必须先知道就是在 C 中怎么释放这个指针。 哪怕同样是 C 的非托管内存, new 或 malloc 之类的编译器的内存函数都是不能跨模块的。
难道说在C里面申请的内存在C#里不能释放?

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

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