[英]DirectShow cast sampleGrabber to ISampleGrabber
我有一个奇怪的错误,我无法绕过头脑。 我有一个在运行的单独线程中创建的图表,我正在尝试访问在控制台应用程序中工作的线程之外的IBaseFilter sampleGrabber
但是我将代码移动到一个新项目,并且我正在尝试将sampleGrabber
为ISampleGrabber
运行时抱怨空引用异常。 如果我调试sampleGrabber
它确实有接口ISampleGrabber
但是我不能再抛出它了。 在运行图形的线程中移动代码允许我进行转换,但它不适合我的应用程序。
如何通过将一个sampleGrabber
为ISampleGrabber
失败来显示null引用异常?
问题是DirectShow过滤器是早期的COM类,它们在引用计数,接口,标记,持久性的一部分中实现COM的子集 - 基本上所有好事都持续了多年 - 但是它们完全忽略了公寓。 DirectShow本身是多线程的,通常有一个控制线程,并且有工作流线程。 DirectShow概念假设您可以轻松地在线程之间传递接口指针,并且不会涉及,预期和需要编组。
然后.NET检查了COM包装器,而DirectShow.NET包装了接口指针,好像它们是功能齐全的公寓感知COM指针一样。 与此同时,Microsoft停止向DirectShow提供更新(例如,使用免费的线程编组器提供Sample Grabber),最终在.NET上遇到问题时,您无法通过接口指针执行一个简单的操作。
在本机代码域中使用API仍然没有问题,因为您可以跳过编组并使用直接指针。
您在一个公寓上构建图形,然后您从另一个公寓的Sample Grabber中回复(或者,在您的方案中,您只需在工作线程上执行某些操作)。 您不能使用原始接口指针,尤其是 那些在成员变量中,因为.NET运行时检查会遇到公寓不匹配,尤其是试图编组另一个公寓的接口指针。
如果它是带有源代码的自定义过滤器,您可以添加自定义IMarshal
实现或利用免费的线程编组器来修复本机代码端的.NET问题,或者添加帮助程序以跨公寓传递指针。
在.NET代码域中,最好的方法是避免使用来自多个公寓的指针。 可能有选择,但我认为最简单的选择是
CLSID_FilterGraphNoThread
版本的Filter Graph Manager 也就是说,要么使用STA,要么没有额外的线程接触指针,否则不使用STA。
在玩了IGlobalInterface并思考了Roman的评论后,我意识到设置处理samplegrabber的函数最好是在另一个线程中,从而绕过STA。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.