COM组件:可连接对象的VC实现
来源:互联网 发布:vm centos 桥接 编辑:程序博客网 时间:2024/06/06 13:21
我们之前使用的COM组件都是由客户端发起请求,而COM组件提供服务,这样的通信都是单向的,但是有时我们需要双向的通信,比如当一个已经提供服务的COM组件对象触发某个保留的事件时,在前一段时间我们并不知道该怎么做,而现在明确了,但是COM组件已经提供服务,我们对于该事件的处理只能在客户端实现,这时候可连接对象就有了它用武之地了。现在我们说说可连接对象是怎么实现的吧
第一步建立ATL项目,暂时命名为link_obj吧,然后添加ATL简单对象,sobj,这里需要注意的是,要支持连接点,
:想到会自动生成一个_IsobjEvents事件接口,当然还有相应的DIID___IsobjEvents,这个接口就是出接口也就是说,该接口是要我们在客户端实现的接口,为该接口添
加测试成员函数HRESULT Msg,为了添加该成员函数,我们需要将idl以及link_obj_i.h文件中的接口定义都要进行改变,也就是说接口的定义涉及到着两个文件,在idl
中添加
importlib("stdole2.tlb");[uuid(9DB001A9-2F50-42A5-BE06-6EC2A8111A58)]dispinterface _IsobjEvents{properties:methods:[id(1)] HRESULT Msg();};
我们只需要注意添加Msg这一行,
在link_obj_i.h文件中则添加
#if defined(__cplusplus) && !defined(CINTERFACE) MIDL_INTERFACE("9DB001A9-2F50-42A5-BE06-6EC2A8111A58") _IsobjEvents : public IDispatch {STDMETHOD(Msg)(); };
为了测试,Msg函数要在Advise即连接时执行,那么我们要做的操作就是
STDMETHOD(Advise)(IUnknown *pUnkSink, /* [out] */ __RPC__out DWORD *pdwCookie){_IsobjEvents*he=static_cast<_isobjevents>(pUnkSink);he->Msg();return S_OK;}
这样启动生成即可,就得到了.dll文件,现在我们要实现的就是客户端的程序了。
#include<iostream>using namespace std;#include"D:\project\link_obj\link_obj\link_obj_i.c"#include"D:\project\link_obj\link_obj\link_obj_i.h"class CSkin : public _IsobjEvents{public:CSkin(void){}~CSkin(void){}private:DWORD m_dwRefCount;public:HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObject){if (iid == DIID__IsobjEvents){m_dwRefCount++;*ppvObject = (void *)this;return S_OK;}if (iid == IID_IUnknown){m_dwRefCount++; *ppvObject = (void *)this;return S_OK;}return E_NOINTERFACE;}ULONG STDMETHODCALLTYPE AddRef(){m_dwRefCount++;return m_dwRefCount;}ULONG STDMETHODCALLTYPE Release(){ULONG l;l = m_dwRefCount--;if ( 0 == m_dwRefCount){delete this;}return l;}HRESULT STDMETHODCALLTYPE GetTypeInfoCount( /* [out] */ __RPC__out UINT *pctinfo){return S_OK;}HRESULT STDMETHODCALLTYPE GetTypeInfo( /* [in] */ UINT iTInfo,/* [in] */ LCID lcid,/* [out] */ __RPC__deref_out_opt ITypeInfo **ppTInfo){return S_OK;}STDMETHOD(Msg)(){::MessageBoxA(NULL,"正在执行Msg函数",0,0);return S_OK;}HRESULT STDMETHODCALLTYPE GetIDsOfNames( /* [in] */ __RPC__in REFIID riid,/* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR *rgszNames,/* [range][in] */ UINT cNames,/* [in] */ LCID lcid,/* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID *rgDispId){return S_OK;}/* [local] */ HRESULT STDMETHODCALLTYPE Invoke( /* [in] */ DISPID dispIdMember,/* [in] */ REFIID riid,/* [in] */ LCID lcid,/* [in] */ WORD wFlags,/* [out][in] */ DISPPARAMS *pDispParams,/* [out] */ VARIANT *pVarResult,/* [out] */ EXCEPINFO *pExcepInfo,/* [out] */ UINT *puArgErr){switch(dispIdMember) // 根据不同的dispIdMember,完成不同的回调函数,事件函数的ID编号{case 2:{// 1st param : [in] long lValue.}break;default: break;}return S_OK;}};int _tmain(int argc, _TCHAR* argv[]){::CoInitialize(NULL);//创建COM对象实例IClassFactory*pcf=NULL;HRESULT hr=::CoGetClassObject(CLSID_sobj,CLSCTX_ALL,NULL,IID_IClassFactory,(void**)&pcf);Isobj* obj=NULL;hr=pcf->CreateInstance(NULL,IID_Isobj,(void**)&obj);pcf->Release();IConnectionPointContainer*ICPC=NULL;hr=obj->QueryInterface(IID_IConnectionPointContainer,(void**)&ICPC);IConnectionPoint*ICP=NULL;hr=ICPC->FindConnectionPoint(DIID__IsobjEvents,&ICP);CSkin *psk=new CSkin();IUnknown* pUk=NULL;hr=psk->QueryInterface(IID_IUnknown,(void**)&pUk);DWORD dw;ICP->Advise(pUk,&dw);ICP->Unadvise(dw);::CoUninitialize();return 0;}
连接过程可以自己写,也可以使用系统默认的链接函数,均可
- COM组件:可连接对象的VC实现
- com可连接对象的实现
- C#创建VC可调用的COM组件
- COM进程外组件的实现vc++
- 对COM可连接对象机制的理解
- COM原理及应用---- 可连接对象
- COM原理及应用----可连接对象
- COM原理及应用---可连接对象
- COM中的可连接对象与连接点机制及其MFC程序实现
- COM中的可连接对象与连接点机制及其MFC程序实现
- COM中的可连接对象与连接点机制及其MFC程序实现
- COM中的可连接对象与连接点机制及其MFC程序实现
- COM中的可连接对象与连接点机制及其MFC程序实现
- 正确释放WORD对象(COM组件) COMException: 被调用的对象已与其客户端断开连接
- COM组件对象如何实现索引属性
- COM组件设计与应用16 - 连接点(vc.net)
- VC中调用COM组件的方法
- VC调用C#写的COM+组件
- Win7下搭建WAMP环境
- log4cpp之Category
- MT4 编程参考
- Struts2理论
- 黑马程序员_IO流——RandomAccessFile
- COM组件:可连接对象的VC实现
- InstallUtil在windows服务中的使用
- 正确理解线程等待和释放(wait/notify)
- spring3 struts2 整合
- 多系统交互问题的处理
- 取消0111前面的多余0
- 宫廷中式风格和园林中式风格的区别
- Windows环境下32位汇编语言程序设计(典藏版)(含CD光盘1张)
- 手动配置Struts2程序