如何接收COM组件事件(100分奉上)

一个硬件厂家提供的设备,现在要读取这个设备的事件。厂家做了一个COM组件,我要在我的DLL中访问这个组件。
现在主要是接收事件这块出问题了。
我在VC6.0、WindowsXP下开发。
其实,本来厂家是提供了DEMO程序的,如果照着那个DEMO做很容易的。
但因为我不能使用MFC的东西(主要是为了平台兼容),所以很费劲。
接收事件我用的是网上提供的CSink类的方法,就是继承IDispEventImpl而自己写的类,在这个类中接收事件。
类如下:
static _ATL_FUNC_INFO info2 =
{
CC_STDCALL, // Calling convention.
VT_HRESULT, // Return type.
2, // Number of arguments.
{ VT_BSTR, VT_I2 } // Argument types.
};
class CSvrEvent :
public CRefCount, public IDispEventImpl<IDC_TMPE_ID,CSvrEvent,
&__uuidof(IServerEvents), // Source interface GUID.
&LIBID_CSSAppServer, // typelib ID containing source interface.
1, // Major version # of LIBID_COMOBJLib. 0> // Minor version # of LIBID_COMOBJLib.
{
public:
CSvrEvent();
CSvrEvent(IServer *pIApplet);
~CSvrEvent(void);

BEGIN_SINK_MAP(CSvrEvent)
SINK_ENTRY_INFO(IDC_TMPE_ID,__uuidof(IServerEvents), 0x00000001, ControllerDetected, &info2)
SINK_ENTRY_INFO(IDC_TMPE_ID,__uuidof(IServerEvents), 0x00000002, ControllerOnline, &info2)
SINK_ENTRY_INFO(IDC_TMPE_ID,__uuidof(IServerEvents), 0x00000003, ControllerOffline, &info2)
SINK_ENTRY_INFO(IDC_TMPE_ID,__uuidof(IServerEvents), 0x00000004, DoorStatusChanged, &info4)
SINK_ENTRY_INFO(IDC_TMPE_ID,__uuidof(IServerEvents), 0x00000005, PointStatusChanged, &info4_1)
SINK_ENTRY_INFO(IDC_TMPE_ID,__uuidof(IServerEvents), 0x00000006, ControllerSearchEnd, &info1)
SINK_ENTRY_INFO(IDC_TMPE_ID,__uuidof(IServerEvents), 0x00000007, NetNodeOnline, &info1)
SINK_ENTRY_INFO(IDC_TMPE_ID,__uuidof(IServerEvents), 0x00000008, NetNodeOffline, &info1)
SINK_ENTRY_INFO(IDC_TMPE_ID,__uuidof(IServerEvents), 0x00000009, UncommonDoorEvent, &info4_2)
SINK_ENTRY_INFO(IDC_TMPE_ID,__uuidof(IServerEvents), 0x0000000a, HistoryEvent, &info1_1)
SINK_ENTRY_INFO(IDC_TMPE_ID,__uuidof(IServerEvents), 0x0000000b, UserAreaChanged, &info4_3)
END_SINK_MAP()

// IUnknown methods
ULONG STDMETHODCALLTYPE AddRef(void);
ULONG STDMETHODCALLTYPE Release(void);
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void * *ppvObj);

// 组件发出的事件函数
STDMETHODCALLTYPE ControllerDetected(_bstr_t NodeIName, short CtrlAddr);
STDMETHODCALLTYPE ControllerOnline(_bstr_t NodeName, short CtrlAddr);
STDMETHODCALLTYPE ControllerOffline(_bstr_t NodeName, short CtrlAddr);

STDMETHODCALLTYPE DoorStatusChanged(_bstr_t NodeName, short CtrlAddr, long DoorAddr, long Status);
STDMETHODCALLTYPE PointStatusChanged(_bstr_t NodeName, short CtrlAddr, short PointAddr, long Status);

STDMETHODCALLTYPE ControllerSearchEnd(_bstr_t NodeName);
STDMETHODCALLTYPE NetNodeOnline(_bstr_t NodeName);
STDMETHODCALLTYPE NetNodeOffline(_bstr_t NodeName);

STDMETHODCALLTYPE UncommonDoorEvent(_bstr_t NodeName,WORD EventType,WORD CtrlAddr,WORD DoorAddr);

STDMETHODCALLTYPE HistoryEvent(long Events);
STDMETHODCALLTYPE UserAreaChanged (_bstr_t NodeName, long ZoneNo, long CardNo, short Area);
};

下面是在初始化时引用这个事件类的代码:
COSERVERINFO ServerInfo;
MULTI_QI Results;

ServerInfo.dwReserved1 = 0;
ServerInfo.dwReserved2 = 0;
ServerInfo.pAuthInfo =NULL;
ServerInfo.pwszName = L"192.168.0.106"; //远程服务器机器名

Results.pIID = &IID_IServer;
Results.pItf = NULL;

HRESULT hr;
hr = CoCreateInstanceEx(CLSID_Server,NULL,
CLSCTX_REMOTE_SERVER,&ServerInfo,1,&Results);
if(FAILED(hr))
{
MessageBox(NULL, "Connect to Server failed","Error",MB_OK | MB_ICONSTOP);
return FALSE;
}
Results.pItf->QueryInterface(&m_pServer);

CComPtr<IConnectionPointContainer> pCPC;
CComPtr<IConnectionPoint> pPC;
hr = m_pServer.QueryInterface(__uuidof(IConnectionPointContainer), (void **)&pCPC);
if (hr != S_OK)
{
return;
}
hr = pCPC->FindConnectionPoint(DIID_IServerEvents,&pPC);
if (hr != S_OK)
{
return;
}

CSvrEvent ServerEvent;
m_pServerEvent = new CSvrEvent(m_pServer);
CComPtr<IUnknown> pUnk;


CLSID clsid;
if(FAILED(::CLSIDFromProgID(L"CSSServer.NetNode.1",&clsid)))
{
return;
}

IDispatch * m_pDispMon;
// 由 CLSID 启动组件,并得到 IDispatch 指针
hr = ::CoCreateInstance(clsid, NULL, CLSCTX_ALL, IID_IDispatch, (void **)&m_pDispMon);
if (hr != S_OK || m_pDispMon == NULL)
{
// AfxMessageBox("创建CooMonitor组件失败。");
return;
}
// 注册事件类
hr = m_pServerEvent->DispEventAdvise(m_pServer);
if (hr != S_OK)
{
return;
}

现在编译没问题,初始化也没问题,就是当程序运行、设备上线的事件被触发时,会发生断言,调试这个异常时来到ATLCOM.H中,错误出现在这个文件的InvokeFromFuncInfo函数中的如下代码:
HRESULT hr = DispCallFunc(
&thunk,
0,
info.cc,
info.vtReturn,
info.nParams,
info.pVarTypes,
pVarArgs,
pvarResult);
ATLASSERT(SUCCEEDED(hr));

以上代码中,hr=0x80070057,其含义是“参数不正确”。

我检查了多次参数,我定义的info2 没问题呀。如下:

static _ATL_FUNC_INFO info2 =
{
CC_STDCALL, // Calling convention.
VT_HRESULT, // Return type.
2, // Number of arguments.
{ VT_BSTR, VT_I2 } // Argument types.
};

ControllerOnline函数是设备上线时触发的,而ControllerOnline的参数是_bstr_t,难道说_bstr_t和VT_BSTR不是一回事?该怎么弄呢?
请各位大师帮忙啊。多谢,100分奉上!
...全文
3713 169 打赏 收藏 转发到动态 举报
写回复
用AI写文章
169 条回复
切换为时间正序
请发表友善的回复…
发表回复
wanglei5695312 2010-07-17
  • 打赏
  • 举报
回复
呵呵,好,好帖,
aichunyu 2010-05-23
  • 打赏
  • 举报
回复
去掉IDispEventImpl,改成IDispEventSimpleImpl
kingyond888 2010-04-18
  • 打赏
  • 举报
回复
用vs2008自动生成ActiveX中的MFC类吧。
klopow 2010-04-17
  • 打赏
  • 举报
回复
难道是因为。。。
http://support.microsoft.com/kb/288724
http://support.microsoft.com/kb/241810
mfc28jacy 2010-04-12
  • 打赏
  • 举报
回复
顶楼主 希望多发技术贴
xiaoguizl 2010-04-12
  • 打赏
  • 举报
回复
都看不懂~
lmc158 2010-04-12
  • 打赏
  • 举报
回复
参数类型的 _bstr_t 全部改成 BSTR,这些函数是被别人调用的,不能随便更换参数类型
iidzy 2010-04-12
  • 打赏
  • 举报
回复
 我的搜藏:http://sousb.com/books/,这些书多是沉淀下来的极品,涵盖了C/C++,JAVA,Windows程序设计,MFC,数据结构和算法,软件工程,Linux,OpenGL/D3D 这些方向。
binghan1589 2010-04-12
  • 打赏
  • 举报
回复
完全看不懂
A583211725 2010-04-12
  • 打赏
  • 举报
回复
学到了
wltianxia2010 2010-04-11
  • 打赏
  • 举报
回复
顶,超好!!
xuyuanyuan717818 2010-04-10
  • 打赏
  • 举报
回复
看不懂
donkeyjie 2010-04-10
  • 打赏
  • 举报
回复
学习学习
q412605752 2010-04-10
  • 打赏
  • 举报
回复
我看网上的文章说:模板类 IDispEventImpl 可用于在 ATL 类中提供连接点接收器支持。
引用地址:http://blog.csdn.net/HotSoftg/archive/2007/06/09/1645710.aspx
那是不是说明我这种DCOM组件不能用IDispEventImpl
趙大叔 2010-04-09
  • 打赏
  • 举报
回复
代码多啊
netlover2008 2010-04-09
  • 打赏
  • 举报
回复
积分中。。。
binghe1979 2010-04-09
  • 打赏
  • 举报
回复
不知道。顶一下
macklau 2010-04-09
  • 打赏
  • 举报
回复
学习了................
csl22 2010-04-09
  • 打赏
  • 举报
回复
xuexi
有这么多朋友关注十分感谢!不一一回了。
没想到不小心成了“推荐贴”。
加载更多回复(147)

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧