C++ 正在调用DirectShow样本抓取器,但';这';回调中为空

C++ 正在调用DirectShow样本抓取器,但';这';回调中为空,c++,windows,webcam,directshow,samplegrabber,C++,Windows,Webcam,Directshow,Samplegrabber,我正在研究DirectShow filtergraph的基本实现,以获取图像 从我的应用程序中的网络摄像头。我已经阅读了文档并创建了一个简单的 实施我创建这个图:设备-->采样捕获器->空渲染器 我正在检查所有可能的结果值,并且从SDK中没有得到任何错误 问题: 不知何故,我的回调被正确调用了,但每当我在回调中添加任何代码时 回调函数(对SampleCB和BufferCB都有效)是我的应用程序 无声地崩溃 我在我的BufferCB中添加了一个断点,我看到'this'是0x0000000/NULL

我正在研究DirectShow filtergraph的基本实现,以获取图像 从我的应用程序中的网络摄像头。我已经阅读了文档并创建了一个简单的 实施我创建这个图:设备-->采样捕获器->空渲染器

我正在检查所有可能的结果值,并且从SDK中没有得到任何错误

问题:

不知何故,我的回调被正确调用了,但每当我在回调中添加任何代码时 回调函数(对SampleCB和BufferCB都有效)是我的应用程序 无声地崩溃

我在我的BufferCB中添加了一个断点,我看到'this'是0x0000000/NULL。 因为我在创建图表时检查了所有的结果值,所以我的猜测是 图形设置正确,此问题可能与COM有关。。但这是 只是胡乱猜测

因为Windows 7.0 SDK不提供包含接口的qedit.h 对于ISampleGrabber接口,我自己创建了这个文件,并添加了相关的 界面(我在谷歌搜索时在帖子的某个地方找到了内容)

我从文档中复制了saveGraph函数,以便在中测试该图 图表编辑。当我添加渲染节点时,我看到它会自动进行颜色转换 节点由GraphiEdit编辑。当我使用渲染器运行图形时,我可以看到图像 从网络摄像头(在GraphiEdit中)

有人知道我如何调试这个或这个错误可能是什么吗?可以吗 与COM有关吗

更新:尝试访问my
中的成员时调用堆栈ISampleGrabberCB

ntdll.dll!_ZwRaiseException@12()  + 0x12 bytes  
ntdll.dll!_ZwRaiseException@12()  + 0x12 bytes  
msvcr100d.dll!__lock_fhandle(int fh)  Line 467  C
qedit.dll!CSampleGrabber::Receive()  + 0x18c bytes  
qedit.dll!CTransformInputPin::Receive()  + 0x33 bytes   
quartz.dll!CBaseOutputPin::Deliver()  + 0x22 bytes  
quartz.dll!CVideoTransformFilter::Receive()  + 0x1aa bytes  
quartz.dll!CTransformInputPin::Receive()  + 0x33 bytes  
quartz.dll!CBaseInputPin::ReceiveMultiple()  + 0x33 bytes   
qcap.dll!COutputQueue::ThreadProc()  + 0x103 bytes  
qcap.dll!COutputQueue::InitialThreadProc()  + 0x16 bytes    
kernel32.dll!@BaseThreadInitThunk@12()  + 0x12 bytes    
ntdll.dll!___RtlUserThreadStart@8()  + 0x27 bytes   
ntdll.dll!__RtlUserThreadStart@8()  + 0x1b bytes    

谢谢

这个问题不太可能只与COM有关。您建议COM似乎以某种方式调用您的回调接口,而它最终是
NULL
。但是如果是这样的话,即使不向回调实现添加任何代码,您也会看到崩溃

您可能知道,COM中的所有接口函数都是虚拟的。调用这样一个函数首先需要取消对接口指针的引用,并读取相应的
vtable
条目的内容。因此,在
NULL
接口指针上调用
virtual
函数会立即导致访问冲突。OTOH调用<虚代码> <代码null >代码>对象是可以的(至少从实现的角度来看,将C++标准放在一边)。
我建议您仔细查看调用堆栈。我相信COM方法被正确调用了。然而,在您的特定示例中,您可能不会直接实现COM回调方法,相反,它可能会被一些包装器代码调用(很可能是DirectShow库)。您应该在那里查找问题。

因为qedit.h不再在Windows SDK上,所以您必须获得与示例抓取器相关的接口的定义。一种方法是使用旧的SDK,所有的头仍然在上面。另一种方法是从类型库导入接口。您可以在代码中重新定义它们

您可以从以下位置获取正确的定义:


因为您没有
\uuu stdcall
,所以使用了错误的调用约定,并且您的

,这太多代码了。还有太多的
(void**)&something
无法理解它使用的指针。你到底是如何定义
ISampleGrabberCB
?如果定义不正确,症状将与您的症状完全相同。下面是你需要做的:Roman R,谢谢,这是我定义它的方式:我将尝试使用你粘贴的一个你缺少的
\uu stdcall
AKA
STDMETHODCALLTYPE
-这就是原因。Roman R,你是最好的!我为SampleCB和BufferCB添加了“STDMETHODCALLTYPE”,现在“this”不再为NULL。我来读一下。嗨,瓦尔多,谢谢你的回复。当我尝试在ISampleGrabberCB类中使用成员时,它会与上面问题中粘贴的调用堆栈一起崩溃。我不知道为什么会崩溃。
struct __declspec(uuid("0579154a-2b53-4994-b0d0-e773148eff85"))
ISampleGrabberCB : IUnknown
{
  virtual HRESULT __stdcall SampleCB (double SampleTime, struct IMediaSample * pSample ) = 0;
  virtual HRESULT __stdcall BufferCB (double SampleTime, unsigned char * pBuffer, long BufferLen ) = 0;
};