呵呵,多年没有搞COM相关的东西,这次由于公司项目的需要又重新学习了COM中与项目相关的部分技术,不过COM技术还是博大精深,敝人也是初探皮毛。本BLOG是对在代理/存根模式下COM组件调用的方法与兄弟们探讨一下。希望能对大家有所帮助。
COM组件对外输出接口有两种模式:TLB库((Type Library)模式和代理/存根(Proxy/stud)模式。如果COM组件是通过TLB库模式输出的时候,将会生成一个.tlb文件,这种方法客户端调用也方便(直接导入即可),同时支持跨语言开发和调用,所以是VC默认的COM接口输出模式。但是该模式将不支持部分IDL语言定义的接口属性,例如:size_is, length_is,[]ref等相关属性。关于tlb的说明请参考http://msdn.microsoft.com/en-us/library/aa366757(v=vs.85).aspx文档。代理/存根(Proxy/stud)模式相对就比较麻烦,并且不能支持跨语言开发和调用,但是可以很好的支持IDL语言定义的各种属性。下面我们主要说明一下代理/存根(Proxy/stud)模式的生产和组件调用。关于IDL接口的定义和说明请参考http://msdn.microsoft.com/en-us/library/aa367091(v=VS.85).aspx文档。
代理/存根(Proxy/stud)模式下COM组件或者服务的生成:由于VC编译器默认生成的是tlb库模式,所以首先需要通过/notlb编译选项告诉编译器我们不需要tlb库输出,同时需要在资源文件(.rc)中将导入tlb库的命令取消(TYPELIB "Interface.tlb")。如果为services服务,在执行前面步骤操作后需要编写一个.mk文件。该文件主要用来将idl接口文件生产的.h, _i.c, _p.c, dlldata.c编译生产代理/存根(Proxy/stud)需要的dll文件, 并通过nmake -f DataExchangeServer.mk 命令编译和生产dll文件,最后通过regsvr32命令将dll注册为服务。
客户端调用COM组件的流程:首先需要将idl接口生产的.h和_i.c include到客户端项目代码中。并通过下面代码实现COM组件的创建和连接(方法很多,下面只是其中的一种):
CoInitialize(NULL);
IUnknown *m_pUnKnown;
IInterface *pvoid
HRESULT hr;
hr = CoCreateInstance(cliid, NULL, CLSCTX_ALL, IID_IUnknown, (void **)&m_pUnknown);
hr = m_pUnknown->QueryInterface(iid, &pvoid);
CoUninitialize();