在直接显示过滤器中调用约定

时间:2014-02-28 16:35:52

标签: c++ com directshow

当我调用我的过滤器getpin()方法时,我得到以下异常:

  

运行时检查失败#0 - 未正确保存ESP的值   跨函数调用。这通常是调用a的结果   用一个带有函数指针的调用约定声明的函数   用不同的调用约定声明。

所以似乎使用了错误的呼叫对话

我试图在过滤器标题中修复此问题:

更改:

CBasePin*  GetPin(int n);

要:

CBasePin* __stdcall GetPin(int n);

但这不会编译,因为它说(翻译自德语)

  

覆盖虚函数仅通过调用约定

与CBaseFilter :: GetPin不同

我还尝试在项目配置中设置调用约定,但这不起作用。

那我现在该怎么办?

这是过滤器界面:

class MyFilter : public  CBaseFilter, public IMyFilter
{
public:

    DECLARE_IUNKNOWN;


    MyFilter(LPUNKNOWN pUnk, HRESULT* phr);
    virtual ~MyFilter(void);

    int  GetPinCount();
    CBasePin* GetPin(int n);


    void acceptFilterInput(LPCWSTR pinname, IMediaSample* sample);

    static CUnknown* WINAPI CreateInstance(LPUNKNOWN pUnk, HRESULT *phr);
    STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv);

    STDMETHODIMP STDMETHODCALLTYPE  StartRecording();
    STDMETHODIMP STDMETHODCALLTYPE Pause();
    STDMETHODIMP STDMETHODCALLTYPE Stop();

    CCritSec m_lock_filter;

    CBaseInputPin* pin0;
    CBaseInputPin* pin1;
    CBaseInputPin* pin2;

    MCMyOutputPin *outpin;
private:

    CCritSec m_critSec;

    std::vector<IMediaSample*> samplesPin0;
    std::vector<IMediaSample*> samplesPin1;
    std::vector<IMediaSample*> samplesPin2;

    LPCWSTR currentInputPin;


    void workerThread();

    void processQueue(std::vector<IMediaSample*> pPinSamples);


};

这就是我使用过滤器的方式:

int static doSomeWork()
{

    CoInitialize(NULL);
    IGraphBuilder* pGraph = NULL;
    IMediaControl* pMediaControl = NULL;
    IMediaEvent* pMediaEvent = NULL;

    HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_ALL, IID_IFilterGraph, (void **) &pGraph);

    if(hr < 0)
    {
        return -1;
    }
    IBaseFilter* pSource = NULL;
    pGraph->QueryInterface(IID_IMediaControl, (void **) pMediaControl);
    pGraph->QueryInterface(IID_IMediaEvent, (void **) pMediaEvent);
    pGraph->AddSourceFilter(TEXT("C:\\TEMP\\video1.avi"), 0, &pSource);

    IPin* pSourceOut = GetPin(pSource, PINDIR_OUTPUT);
    IBaseFilter* pAVISplitter = NULL;
    CoCreateInstance(CLSID_AviSplitter, NULL,   
                             CLSCTX_INPROC_SERVER,
                             IID_IBaseFilter,
              (void**)&pAVISplitter);

    IPin* pAvIIn = GetPin(pAVISplitter, PINDIR_INPUT);

    pGraph->AddFilter(pAVISplitter, L"Splitter");
    pGraph->Connect(pSourceOut, pAvIIn);

    IPin* pAVIOut = GetPin(pAVISplitter, PINDIR_OUTPUT);


    MyFilter* myfilter;
    hr = CoCreateInstance(CLSID_MyFilter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)& myfilter);
    if(hr < 0)
    {
        return -1;
    }
    IPin* myfilterIn = myfilter->GetPin(0);
    IPin* myFilterOut = myfilter->GetPin(3);
    pGraph->Connect(pAVIOut, myfilterIn);

    pGraph->Render(myFilterOut);

    CoUninitialize();


    return 0;
}

错误在“myFilter-&gt; GetPin(0)”

1 个答案:

答案 0 :(得分:4)

您遇到的问题是由于违反了COM基础原因造成的。

MyFilter* myfilter;
hr = CoCreateInstance(CLSID_MyFilter, NULL, CLSCTX_INPROC_SERVER, 
    IID_IBaseFilter, (void **)& myfilter);

CoCreateInstanceQueryInterface或类似IID_IBaseFilter参数将返回IBaseFilter*指针。您应该正确地重新解释收到的指针以便进一步使用。

您选择IBaseFilter*,然后将重新解释转换为MyFilter* - 这不会起作用。你仍然有IBaseFilter*指针,并且在其上调用其他方法会导致未定义的行为。

长话短说,你不能(你可以,但这里答案的初级版本是你不能)在控制应用程序上有MyFilter*指针,你只能有COM接口指针。