我正在使用DSPACK DirectShow组件库在Delphi 6 Pro中构建DirectShow过滤器。在他们的Push Source Filter示例中,对于某些项目,他们使用CoTaskMemAlloc(),尤其是为Windows API调用中使用的项目分配内存,例如视频位图信息头(PVIDEOINFOHEADER)和O / S文件操作中使用的缓冲区,如ReadFile等。 。使用通常的(Object).Create()调用或直接创建动态数组来分配其他项目。
在DirectShow过滤器中必须使用CoTaskMemAlloc()的规则/指南是什么?
@Vinay的这个SO回复给出了简洁的答案,它应该与任何将跨越过程边界的内存一起使用:
但我想知道在DirectShow过滤器中是否存在任何常见的内存分配错误,尤其是在通过输入/输出引脚呈现或提供数据时,由于我未能使用CoTaskMemAlloc()。 / p>
答案 0 :(得分:3)
CoTaskMemAlloc是COM内存分配器的一部分。它与CoTaskMemRealloc和CoTaskMemFree一起使用。
COM内存分配器旨在允许COM客户端分配稍后由COM服务器释放的内存,反之亦然。只有当内存的所有权通过COM客户端/服务器边界传输时,才需要使用它。
这解决了一个非常常见的互操作问题。不同的编程系统具有不同的堆实现。因此,在一个堆上分配的内存只能在同一堆上解除分配。如果你有一个返回字符串的COM方法,比如说你有问题。如果服务器和客户端使用不同的堆,您现在需要让服务器在完成后解除分配字符串。 COM分配器通过作为所有参与者可以使用的单个共享堆来解决这个问题。
说到这一点,得知BSTR(即Delphi中所谓的WideString)与COM分配器一起分配也就不足为奇了。
我不熟悉DirectShow接口,但COM的原理是通用的。在服务器中实现GetMediaType时,必须分配返回的结构。由于客户端必须释放该结构,如文档中所指定的,显然您必须使用COM分配器,因为这是您的客户将使用的。
您还提到了ReadFile。完全没有必要使用COM分配器,因为调用者负责分配和释放缓冲区。
底线是COM是一个接口合约。如果指针穿过接口边界并将所有权从客户端传输到服务器,反之亦然,则必须使用COM分配器。
答案 1 :(得分:1)
您必须使用CoTaskMemAlloc进行COM中将传递给外部世界的任何内存分配。 Directshow filtrers使用COM并将缓冲区从过滤器传递到过滤器以避免复制数据。