0

我对 COM 知之甚少,在 Google 中搜索 COM somhow 根本没有找到 COM(可能是因为它搜索的是 .com 地址)。

我们正在使用视频捕获硬件。它的 SDK 允许我们在捕获帧时注册回调。对象接口作为参数传递给该回调,我们可以通过查询该对象来获取大缓冲区地址(到捕获的帧像素)和其他信息。

现在看来,调用Release()实际上并没有删除内存,而是减少了引用计数,当计数达到0时,它被删除了,对吧?那么,关于上面提到的那个大缓冲区地址,使用“delete”关键字“删除”缓冲区怎么样?

似乎我们的程序(不是我写的,编写程序的人退出了公司)将指向缓冲区的指针复制到某个类中,但从未在回调中调用任何 Release()。后来,缓冲区在类中被“删除”。似乎 Release()ing 框架接口对象也删除了缓冲区。但它们是一样的吗?

COM 以某种方式计算引用,但如果用户的代码只是删除该内存会发生什么?如果我的问题含糊不清,我很抱歉。简而言之,删除从 COM 对象获取的缓冲区是否安全。

简化代码:可疑情况

void mycallback(IFrame f)
{
  char* buffer;
  f->GetBuffer(buffer);
  MyClass m(buffer);
  ...
}

MyClass::DeleteBuffer()
{
  delete m_buffer;
}
4

3 回答 3

2

当代码将帧缓冲区内容复制到自己的缓冲区中时,并没有发生什么特别的事情。帧缓冲区仍归 COM 代码所有,代码自己的缓冲区仍归该代码所有。不要删除 COM 缓冲区,当 COM 代码删除它时,这将调用未定义的行为。如果您先调用 AddRef(),则只应在 COM 接口指针上调用 Release()。在这样的场景中,AddRef() 调用是由 COM 代码在调用回调之前进行的。并且 Release() 调用将在回调返回后进行。

在回调中看到帧被复制是很正常的,帧缓冲区通常只在回调期间保持有效。所以以后用的话就得复制。

如果您正在追踪内存泄漏,那么这不太可能是罪魁祸首。如果帧缓冲区存在引用计数问题,那么程序在消耗所有可用内存之前不能持续超过一分钟。

于 2012-10-31T08:51:51.430 回答
0

处理 COM 接口更棘手:-)

  1. 确保匹配 IUnknown::AddRef() 和 IUnknown::Release() 调用
  2. 只要您处于相同的上下文中,您就可以显式删除缓冲区,即使您是从 COM 接口获取的。但请确保在删除后使指针无效,以免出现后期处理问题。

    MyClass::DeleteBuffer() { if(m_buffer) { 删除 m_buffer; m_buffer = null; } }

于 2013-03-12T08:35:13.430 回答
0

尝试使用这个地方操作符删除,CoTaskMemFree

于 2012-10-31T08:49:06.120 回答