C++ 直接显示筛选器中的调用约定
调用过滤器getpin()方法时出现以下异常: 运行时检查失败#0-ESP的值未正确保存 跨越函数调用。这通常是调用 用一个调用约定和一个函数指针声明的函数 使用不同的调用约定声明 因此,似乎使用了错误的呼叫转换 我尝试在筛选器标题中修复此问题: 更改:C++ 直接显示筛选器中的调用约定,c++,com,directshow,C++,Com,Directshow,调用过滤器getpin()方法时出现以下异常: 运行时检查失败#0-ESP的值未正确保存 跨越函数调用。这通常是调用 用一个调用约定和一个函数指针声明的函数 使用不同的调用约定声明 因此,似乎使用了错误的呼叫转换 我尝试在筛选器标题中修复此问题: 更改: CBasePin* GetPin(int n); 致: 但这不会编译,因为上面写着(翻译自德语) 通过调用约定,重写虚拟函数仅与CBaseFilter::GetPin不同 我还尝试在项目配置中设置调用约定,但没有成功 那我现在该怎么办 这是
CBasePin* 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);
};
class MyFilter:public cbase过滤器、public IMyFilter
{
公众:
宣布不知道;
MyFilter(LPUNKNOWN朋克,HRESULT*phr);
虚拟~MyFilter(void);
int GetPinCount();
CBasePin*GetPin(int n);
无效接受过滤器输入(LPCWSTR pinname,IMediaSample*样本);
静态CUnknown*WINAPI CreateInstance(LPUNKNOWN朋克,HRESULT*phr);
STDMETHODIMP非删除查询接口(refid-riid,void**ppv);
STDMETHODIMP STDMETHODCALLTYPE StartRecording();
STDMETHODIMP STDMETHODCALLTYPE Pause();
STDMETHODIMP STDMETHODCALLTYPE Stop();
CCritSec m_锁定滤波器;
CBaseInputPin*pin0;
CBaseInputPin*pin1;
CBaseInputPin*pin2;
mcmyotputpin*outpin;
私人:
CCritSec m_critSec;
std::向量样本PIN0;
std::向量样本PIN1;
std::向量样本PIN2;
LPCWSTR电流输入引脚;
void workerThread();
void processQueue(std::vector-samples);
};
以下是我使用过滤器的方式:
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;
}
int static doSomeWork()
{
共初始化(空);
IGraphBuilder*pGraph=NULL;
IMediaControl*pMediaControl=NULL;
IMediaEvent*pMediaEvent=NULL;
HRESULT hr=CoCreateInstance(CLSID_FilterGraph、NULL、CLSCTX_ALL、IID_IFilterGraph、(void**)和pGraph);
如果(hr<0)
{
返回-1;
}
IBaseFilter*pSource=NULL;
pGraph->QueryInterface(IID_IMediaControl,(void**)pMediaControl);
pGraph->QueryInterface(IID_IMediaEvent,(void**)pMediaEvent);
pGraph->AddSourceFilter(文本(“C:\\TEMP\\video1.avi”)、0和pSource;
IPin*pSourceOut=GetPin(pSource,PINDIR_输出);
IBaseFilter*PAVISPLITT=NULL;
CoCreateInstance(CLSID_)拆分器,空,
CLSCTX_INPROC_服务器,
IID_IBaseFilter,
(void**)和pavisplatter);
IPin*pAvIIn=GetPin(pavisplite,PINDIR_输入);
pGraph->AddFilter(pAVISplitter,L“拆分器”);
PGRAPHE->Connect(PSOURCOUT,pAvIIn);
IPin*pAVIOut=GetPin(PAVISPLITT,PINDIR_输出);
MyFilter*MyFilter;
hr=CoCreateInstance(CLSID\u MyFilter,NULL,CLSCTX\u INPROC\u SERVER,IID\u ibasefiler,(void**)和MyFilter);
如果(hr<0)
{
返回-1;
}
IPin*myfilterIn=myfilter->GetPin(0);
IPin*myFilterOut=myfilter->GetPin(3);
pGraph->Connect(pAVIOut,myfilterIn);
pGraph->Render(myFilterOut);
coninitialize();
返回0;
}
错误出现在“myFilter->GetPin(0)”您遇到的问题是由违反COM基本原理造成的
MyFilter* myfilter;
hr = CoCreateInstance(CLSID_MyFilter, NULL, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, (void **)& myfilter);
CoCreateInstance
或QueryInterface
或类似的IID\u IBaseFilter
参数将返回您的IBaseFilter*
指针。您应该正确地重新解释接收到的指针,以便正确地进一步使用
您使用IBaseFilter*
,然后对MyFilter*
应用reinterpret cast,这是行不通的。您仍然有IBaseFilter*
指针,对其调用其他方法会导致未定义的行为
长话短说,你不能(你可以,但这里答案的初级版本是你不能)在控制应用程序上有
MyFilter*
指针,你只能在那里有COM接口指针。创建一个做同样事情的静态方法。我相信成员函数必须是\uu thiscall
。我不能将其作为静态方法,因为我必须访问成员变量,所以它是一个重写方法,不能是静态的。你可以在一小段代码中重现这个问题吗?@jliv902:考虑到它的DirectShow代码,提供的代码段非常小
MyFilter* myfilter;
hr = CoCreateInstance(CLSID_MyFilter, NULL, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, (void **)& myfilter);