紧急求助:ATL客户与COM组件建立连接点成功,但是无法响应该连接点上的事件

时间:2022-02-23 19:46:45
CUPSvr是进程外的COM组件,ATL客户是一个.EXE,接收类名为CSUCtrlSink,连接点为m_pISuCtrlConnectionPoint,对应于接口_IUPSvrEvents.
在客户程序中首先创建了一个对话框类CSUCtrlDlg,而后直接执行该对话框类的Initialize方法,其代码如下:
bool CSUCtrlDlg::Initialize()
{
//create COM object of CSuCtrlSink
m_pSuCtrlSink = new CComObject<CSUCtrlSink>;

HRESULT hr;
IUnknown* pUnk = NULL;
IConnectionPointContainer* pConnPtContainer = NULL;

hr = m_UpCtrl.CoCreateInstance(__uuidof(CUPSvr));

hr = m_UpCtrl->QueryInterface(IID_IConnectionPointContainer, (void**)&pConnPtContainer);

hr = pConnPtContainer->FindConnectionPoint(__uuidof(_IUPSvrEvents), &m_pISuCtrlConnectionPoint);

CComPtr<IUnknown>spUnk;
m_pSuCtrlSink->QueryInterface(IID_IUnknown, (LPVOID *)&spUnk);

hr = m_pISuCtrlConnectionPoint->Advise(spUnk, &m_dwCookie);

return true;
}
Debug时发现Advise返回S_OK, 而且m_dwCookie=1,但是对于_IUPSvrEvents上的事件,客户程序就是无法响应。
后来看到网上说需要指定客户程序的事件处理函数和连接点上的事件的对应关系,于是在接收类中添加了如下代码
BEGIN_SINK_MAP(CSUCtrlSink)
SINK_ENTRY_EX(0,__uuidof(_IUPSvrEvents), 1, UploadingStarted)
END_SINK_MAP()
但在这种情况下,链接时会出现如下错误:
error C2440: 'static_cast' : cannot convert from '_atl_event_classtype *' to 'ATL::_IDispEventLocator<nID,piid> *'

请大虾们帮忙看看,实在搞不定了,多谢多谢!

9 个解决方案

#1


跟进去看了一下,发现在服务组件invoke是返回的是“member not found", 但是我在接收类上实现了该接口阿,太奇怪了。。。

#2



给大家介绍个技术群

大家一起学习,一起提高

21189212

#3


dispid指定不对

#4


我在_IUPSvrEvents接口上添加了两个method,fun1和fun2,dispid分别是1和2,然后选择实现连接点后自动生成了回调辅助函数Fire_fun1和Fire_fun2,对应dispid分别指定为1和2,不知道这里有什么问题呢,dispid怎么会指定不对呢?

#5


MARK

#6


http://www.vckbase.com/document/viewdoc/?id=1538

#7


你这里搞错了
CComPtr<IUnknown>spUnk;
m_pSuCtrlSink->QueryInterface(IID_IUnknown, (LPVOID *)&spUnk);

hr = m_pISuCtrlConnectionPoint->Advise(spUnk, &m_dwCookie);

应该是:
CComPtr<IUnknown>spUnk;
m_pISuCtrlConnectionPoint->QueryInterface(IID_IUnknown, (LPVOID *)&spUnk);

m_pSuCtrlSink->Advise(spUnk, &m_dwCookie);

因为2个对象Advise方法参数不同,所以报那个连接错误

#8


我也碰到 error   C2440, 把下边的0换成资源id, ok
SINK_ENTRY_EX(0,__uuidof(_IUPSvrEvents),   1,   UploadingStarted) 

#9


引用 7 楼 samsun2000 的回复:
你这里搞错了 
CComPtr <IUnknown> spUnk; 
m_pSuCtrlSink-> QueryInterface(IID_IUnknown,   (LPVOID   *)&spUnk); 

hr   =   m_pISuCtrlConnectionPoint-> Advise(spUnk,   &m_dwCookie); 

应该是: 
CComPtr <IUnknown> spUnk; 
m_pISuCtrlConnectionPoint-> QueryInterface(IID_IUnknown,   (LPVOID   *)&spUnk); 

m_pSuCtrlSink-> Advise(spUnk,   &m_dwCookie); 

因为2个对象Advise方法参数不同,所以报那…

对了,Advise方法为注册调用接口指针,必须用外部的接收器对象指针。

其次如果还有其他的问题你可以用MessageBox()在服务端ExE中跟踪显示一下。

#1


跟进去看了一下,发现在服务组件invoke是返回的是“member not found", 但是我在接收类上实现了该接口阿,太奇怪了。。。

#2



给大家介绍个技术群

大家一起学习,一起提高

21189212

#3


dispid指定不对

#4


我在_IUPSvrEvents接口上添加了两个method,fun1和fun2,dispid分别是1和2,然后选择实现连接点后自动生成了回调辅助函数Fire_fun1和Fire_fun2,对应dispid分别指定为1和2,不知道这里有什么问题呢,dispid怎么会指定不对呢?

#5


MARK

#6


http://www.vckbase.com/document/viewdoc/?id=1538

#7


你这里搞错了
CComPtr<IUnknown>spUnk;
m_pSuCtrlSink->QueryInterface(IID_IUnknown, (LPVOID *)&spUnk);

hr = m_pISuCtrlConnectionPoint->Advise(spUnk, &m_dwCookie);

应该是:
CComPtr<IUnknown>spUnk;
m_pISuCtrlConnectionPoint->QueryInterface(IID_IUnknown, (LPVOID *)&spUnk);

m_pSuCtrlSink->Advise(spUnk, &m_dwCookie);

因为2个对象Advise方法参数不同,所以报那个连接错误

#8


我也碰到 error   C2440, 把下边的0换成资源id, ok
SINK_ENTRY_EX(0,__uuidof(_IUPSvrEvents),   1,   UploadingStarted) 

#9


引用 7 楼 samsun2000 的回复:
你这里搞错了 
CComPtr <IUnknown> spUnk; 
m_pSuCtrlSink-> QueryInterface(IID_IUnknown,   (LPVOID   *)&spUnk); 

hr   =   m_pISuCtrlConnectionPoint-> Advise(spUnk,   &m_dwCookie); 

应该是: 
CComPtr <IUnknown> spUnk; 
m_pISuCtrlConnectionPoint-> QueryInterface(IID_IUnknown,   (LPVOID   *)&spUnk); 

m_pSuCtrlSink-> Advise(spUnk,   &m_dwCookie); 

因为2个对象Advise方法参数不同,所以报那…

对了,Advise方法为注册调用接口指针,必须用外部的接收器对象指针。

其次如果还有其他的问题你可以用MessageBox()在服务端ExE中跟踪显示一下。