问题是 DirectShow 过滤器是早期的 COM 类,它们在引用计数、接口、名字对象、持久性方面实现了 COM 的一个子集——基本上所有的好东西都会持续多年——但是它们完全忽略了公寓。DirectShow 本身是多线程的,通常有一个控制线程,旁边还有工作流线程。DirectShow 概念假定您可以轻松地在线程之间传递接口指针,并且不涉及、预期和要求的封送处理。
然后是带有检查 COM 包装器的 .NET,并且 DirectShow.NET 包装了接口指针,就好像它们是功能齐全的单元感知 COM 指针一样。与此同时,Microsoft 停止了对 DirectShow 的更新(例如,为 Sample Grabber 提供免费的线程封送处理程序),最终您在 .NET 上遇到了这个问题,您无法使用接口指针执行所谓的简单操作。
在本机代码域中使用 API 仍然绝对没有问题,因为您可以跳过那里的编组并使用直接指针。
您在一个公寓上构建图表,然后在另一间公寓上收到来自 Sample Grabber 的回调(或者,在您的场景中,您只需在工作线程上执行某些操作)。您不能使用原始接口指针,尤其是。成员变量中的那些,因为 .NET 运行时检查会遇到单元不匹配,尤其是试图为另一个单元编组接口指针。
如果它是带有源代码的自定义过滤器,您可以添加自定义IMarshal
实现或利用免费线程封送处理程序来修复本机代码端的 .NET 问题,或者添加帮助程序以跨单元传递指针。
在 .NET 代码域中,最好的方法是避免使用来自多个公寓的指针。可能有选择,但我想到的最简单的一个是
也就是说,要么使用 STA,并且没有额外的线程接触指针,要么不使用 STA。