首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在C#中释放在C++中分配的内存

如何在C#中释放在C++中分配的内存
EN

Stack Overflow用户
提问于 2015-05-26 16:47:00
回答 3查看 3.4K关注 0票数 4

我有一个C++动态链接库,它从摄像机读取视频帧。这些帧在通过指向调用方( C#程序)的指针返回的DLL中得到分配。

当C#使用特定的视频帧完成时,它需要清理它。DLL接口和内存管理封装在C#中的一次性类中,因此更易于控制。但是,内存似乎没有被释放/释放。我的进程的内存占用不断增长,在不到一分钟的时间内,我就会在C++ DLL中得到分配错误,因为没有任何内存了。

每个视频帧都超过9MB。代码很多,所以我将简单地提供分配/释放位置/类型/等等。

首先:在C++中为摄像机字节分配原始缓冲区。

代码语言:javascript
运行
复制
dst = new unsigned char[mFrameLengthInBytes];

第二:将原始指针作为无符号字符*从原始指针返回到跨DLL边界,并在C#中转换为C#中的

代码语言:javascript
运行
复制
IntPtr pFrame = VideoSource_GetFrame(mCamera, ImageFormat.BAYER);
return new VideoFrame(pFrame, .... );

现在,IntPtr被传递到VideoFrame类的CTOR中。在CTOR内部,IntPtr被复制到类的内部成员,如下所示:

代码语言:javascript
运行
复制
IntPtr dataPtr;
public VideoFrame(IntPtr pDataToCopy, ...)
{
    ...
    this.dataPtr = pDataToCopy;
}

我的理解是,这是一个浅拷贝,类现在引用原始数据缓冲区。帧被使用/处理/等等。稍后,VideoFrame类被释放,下面的内容被用来清理内存。

代码语言:javascript
运行
复制
Marshal.FreeHGlobal(this.dataPtr);

我怀疑问题是..。dataPtr是一个IntPtr,C#无法知道底层缓冲区实际上是9MB,对吗?有没有办法告诉它在这一点上要释放多少内存?我是不是使用了错误的C#免费方法?有专门针对这种情况的吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-05-26 16:57:50

您需要在正在使用的库中调用相应的“空闲”方法。

通过new分配的内存是C++运行时的一部分,调用FreeHGlobal不能工作。您需要(以某种方式)针对内存调用delete[]

如果这是您自己的库,那么创建一个函数(例如VideoSource_FreeFrame)来删除内存。例:

代码语言:javascript
运行
复制
void VideoSource_FreeFrame(unsigned char *buffer)
{
  delete[] buffer;
}

然后从C#调用它,传入返回的IntPtr

票数 7
EN

Stack Overflow用户

发布于 2015-05-26 16:58:19

您需要(在c++中) delete dst;。这意味着您需要提供一个C#代码可以调用的API,比如FreeFrame(...),它就是这样做的。

票数 3
EN

Stack Overflow用户

发布于 2015-05-26 17:08:57

我同意第一个答案。不要在C#代码中释放它,使用任何神奇的、礼拜化的咒语。在C++中编写一个释放内存的方法,并从您的C#代码中调用它。不要养成在一个堆(本机)中分配内存和释放另一个堆(管理)的习惯,这只是个坏消息。

记住“有效C++”一书中的一条规则:在构造函数中分配内存,并在析构函数中释放。如果在析构函数中不能这样做,可以使用类内方法,而不是全局(甚至更糟)的朋友函数。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30464431

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档