CBaseVideoRenderer派生类中的内存已损坏

时间:2014-06-19 14:04:44

标签: c++ visual-studio-2012 com directshow

我尝试编写一个能够在VS2012项目中捕获基于VIDEOINFO2的流的DirectShow渲染器。为此,我从Windows 7 SDK中获取了基类项目,将其升级到VS2012并构建它。我的渲染器看起来像

class CapturingVideoRenderer : public CBaseVideoRenderer {

public:
    CapturingVideoRenderer(LPUNKNOWN pUnk, HRESULT *phr);
    virtual ~CapturingVideoRenderer(void);
    virtual HRESULT CheckMediaType(const CMediaType *pmt);
    virtual HRESULT DoRenderSample(IMediaSample *pMediaSample);
    virtual HRESULT SetMediaType(const CMediaType *pmt);
    virtual HRESULT StartStreaming(void);

protected:
    typedef CBaseVideoRenderer Base;

public:
    DECLARE_IUNKNOWN;

};

从实现中,重要的部分是构造函数:

CapturingVideoRenderer::CapturingVideoRenderer(LPUNKNOWN pUnk, HRESULT *phr)
        : Base(::CLSID_CapturingVideoRenderer, Name_CapturingVideoRenderer,
        pUnk, phr) {
}

如果我现在创建一个实例(我直接进行调试),应用程序崩溃:

IBaseFilter *filter = nullptr;
CapturingVideoRenderer *renderer = nullptr;
HRESULT hr = S_OK;

obj = new CapturingVideoRenderer(nullptr, &hr);
if (FAILED(hr)) { [...] }

//hr = obj->NonDelegatingQueryInterface(IID_IBaseFilter,
//    reinterpret_cast<void **>(&filter));
hr = obj->QueryInterface(IID_IBaseFilter,
    reinterpret_cast<void **>(&filter));
if (FAILED(hr)) { [...] }

问题似乎是当最后一个基本ctor和我的ctor之间的代码被执行时,vtable(或更多)会以某种方式被破坏。如果我直接调用NonDelegatingQueryInterface(注释掉),它可以工作(但稍后崩溃),但是对QueryInterface的调用崩溃,因为它从CUnkown基类获得实际实现,这是损坏。

虽然我对汇编语言知之甚少,但我还是逐步完成了反汇编。在输入我的ctor的主体之前,执行以下指令,这些指令覆盖位于rax + 18h的基类(CUnknown)参考计数器的一部分以及基础的其他字段类):

000000013FCBABEF  mov         rax,qword ptr [this]
000000014000AC07  lea         rcx,[CapturingVideoRenderer::`vftable' (0140147A28h)]  
000000014000AC0E  mov         qword ptr [rax+18h],rcx 
000000013FCBAC02  mov         rax,qword ptr [this]  
000000013FCBAC0A  lea         rcx,[CapturingVideoRenderer::`vftable' (013FDF7A38h)]  
000000013FCBAC11  mov         qword ptr [rax+20h],rcx  
000000013FCBAC15  mov         rax,qword ptr [this]  

我已经运行了VS2012的静态代码分析,但它没有找到任何有用的东西(来自Windows SDK的基类库中的一些错误的SAL注释)。

最重要的问题当然是:我该如何解决这个问题?

我的其他问题是:在VS2012中使用DirectShow基类是否存在任何已知问题?有可能吗?我是否必须更改一些编译器设置(atm,一切都与项目中的可执行文件相同,它基本上直接来自向导 - 平台工具集v110和Unicode)?

1 个答案:

答案 0 :(得分:0)

似乎你无法以这种方式调试DirectShow过滤器。如果我注册它通常&#34;它工作正常,所以COM似乎在这里做了一些重要的事情......