Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
DirectShow ISampleGrabber.SetCallback在显示C#MessageBox后引发InvalidCastException_C#_Com_Directshow_Directshow.net - Fatal编程技术网

DirectShow ISampleGrabber.SetCallback在显示C#MessageBox后引发InvalidCastException

DirectShow ISampleGrabber.SetCallback在显示C#MessageBox后引发InvalidCastException,c#,com,directshow,directshow.net,C#,Com,Directshow,Directshow.net,我正在使用DirectShow的SampleGrabber从网络摄像头视频中捕获图像。代码是用C#编写的,并使用DirectShow接口的.NET包装器进行COM通信。下面的BufferCB首先将图像数据复制到本地数组变量,禁用SampleGrabber回调,处理接收到的图像数据,并使用MessageBox显示结果 public int BufferCB(double sampleTime, IntPtr pBuffer, int bufferLen) { if (Monitor.Try

我正在使用DirectShow的SampleGrabber从网络摄像头视频中捕获图像。代码是用C#编写的,并使用DirectShow接口的.NET包装器进行COM通信。下面的BufferCB首先将图像数据复制到本地数组变量,禁用SampleGrabber回调,处理接收到的图像数据,并使用MessageBox显示结果

public int BufferCB(double sampleTime, IntPtr pBuffer, int bufferLen)
{
    if (Monitor.TryEnter(lockSync))
    {
         try
         {
              if ((pBuffer != IntPtr.Zero))
              {
                   this.ImageData = new byte[bufferLen];
                   Marshal.Copy(pBuffer, this.ImageData, 0, bufferLen);

                   // Disable callback
                   sampleGrabber.SetCallback(null, 1);

                   // Process image data
                   var result = this.Decode(new Bitmap(this.ImageData));

                   if (result != null)
                   {
                       MessageBox.Show(result.ToString());
                   }

                   // Enable callback
                   sampleGrabber.SetCallback(this,1);
              }
         }
         finally
         {
              Monitor.Exit(this.parent.lockSync);
         }
    }
    return 0;
}
现在,如果
result=null
,因此MessageBox.Show从不运行,那么两个钳制调用sampleGrabber.SetCallback()都将运行,不会出现任何问题。一旦<代码>结果!=null,消息框显示,call sampleGrabber.SetCallback(这个,1)将抛出InvalidCastException,如下所示:

无法将“System.\u ComObject”类型的COM对象强制转换为接口类型“DirectShowInterfaces.ISampleGrabber”。此操作失败,因为对IID为“{6B652FF-11FE-4FCE-92AD-0266B5D7C78F}”的接口的COM组件的QueryInterface调用由于以下错误而失败:不支持此类接口(HRESULT的异常:0x80004002(E_NOINTERFACE))。

如果我在VS调试器中停止并添加一个
((ISampleGrabber)sampleGrabber).SetCallback(sampleGrabber,1)
,我将得到ArgumentException,消息为“找不到对象实例上的方法”


如果有人遇到同样的问题,可以给我一些建议。谢谢。

BufferCB
SampleCB
调用发生在工作线程上,这些线程通常属于MTA。另一方面,图形初始化通常在STA线程上进行。DirectShow API和筛选器自动忽略COM线程规则,而.NET强制执行线程检查。如果尝试在错误线程上使用COM接口指针,则会引发异常。你正好碰到了这个问题


您不需要重置回调然后将其设置回原位。改用
SampleCB
callback,它作为阻塞调用发生。在您完成处理之前,流媒体的其余部分将处于保留状态。

但它没有解释为什么只有在调用MessageBox.Show返回后调用才会失败。在不显示消息框的情况下,它们工作正常。在此线程上使用
sampleGrabber
接口指针是一种违规行为(指针属于不同的COM单元)。它可能会也可能不会立即失败,也可能取决于外部因素。