COM技术初探1

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

http://www.vckbase.com/document/viewdoc/?id=915
2010/4/20
w
页码,4/15(W)
图 1.1 CMath 的三个客户
2.2 DLL
解决上面问题的一个技术是将 CMath 类做成动态链接库 (DLL , Dynamic Link Library) 的形式封装起来 。 在使用这项技术的时候, CMath 的所有方法都将被加到 CMath dll 的引出表 (export list) 中,而且链接器将会产生一个引入库 (import library) 。 这个库暴露了 CMath 的方法成员的符号 。当客户链接引入库时,有一些存根会被引入到可执行文件中,它在运行时通知装载器动态装载 CMath Dll。 当 CMath 位于 dll 中时,他的运行模型见图 1.2
http://www.vckbase.com/document/viewdoc/?id=915
2010/4/20
w
页码,7/15(W)
注意:所有具有 out 属性的参数都需要是指针类型。
1.3 IUnkown 接口
在整个例子除了 IUnkown 这个东西,其他应该不会感到陌生吧! COM 要求 ( 最基本的要求 ) 所有的接口都需要从 IUnknown 接口直接或间接继承,所 以 IUnknown 接口有 " 万恶之源 " 之称。 IUnkown 接口定义了三个方法。 HRESULT QueryInterface([in] REFIID riid,[out] void **ppv); ULONG AddRef(); ULONG Release(); 其中 AddReft() 和 Release() 负责对象引用计数用的,而 QueryInterface() 方法是用于查询所实现接口用的。每当 COM 组件被引用一次就应调用 一次 AddRef() 方法。而当客户端在释放 COM 组件的某个接口时就需要调用 Release() 方法。 这里所讲的请在下面的例子仔细体会。
http://www.vckbase.com/document/viewdoc/?id=915
2010/4/20
w
页码,3/15(W)
一. 没有lib的dll 1.1 建一个没有lib的dll 1.2 调试没有lib的dll 二. 带有lib的dll 2.1 创建一个带有lib的dll 2.2 调试带有引用但没有头文件的dll 三. 带有头文件的dll 3.1 创建一个带有引出信息头文件的dll 3.2 调试带有头文件的dll 四. 小结
图 1.2 CMath 引入库
2.3 COM
" 简单地把 C++ 类定义从 dll 中引出来 " 这种方案并不能提供合理的二进制组件结构。因为 C++ 类那既是接口也是实现。这里需要把接口从实现中分 离出来才能提供二进制组件结构。此时需要有二个 C++ 类,一个作为接口类另一个作为实现类。让我们开始 COM 之旅吧。
三. 纯手工创建一个COM组件 1. 从建工程到实现注册 1.1 创建一个类型为win32 dll工程 1.2 定义接口文件 1.3 增加注册功能 1.3.1 增加一 个MathCOM.def文件 1.3.2 DllRegisterServer()和DllUnregisterServer() 1.4 MathCOM.cpp文件 1.5 小结 2. 实现ISmipleMath,IAdvancedMath接口和DllGetClassObject() 2.1 实现ISmipleMath和IAdvancedMath接口 2.2 COM组件调入大致过程 2.3 DllGetClassObject()实现 2.4 客户端 2.5 小结 3. 类厂 附录 A 我对dll的一点认识
一、 COM 是一个更好的 C++ 1 、 COM 是什么
Don Box 说 "COM IS LOVE" 。 COM 的全称是 Component Object Model 组件对象模型。
2 、从 C++ 到 DLL 再到 COM 2.1 C++
如某一软件厂商发布一个类库 (CMath 四则运算 ) ,此时类库的可执行代码将成为客户应用中不可分割的一部分。假设此类库的所产生的机器码在目 标可执行文件中占有 4MB 的空间。当三个应用程序都使用 CMath 库时,那么每个可执行文件都包含 4MB 的类库代码 ( 见图 1.1) 。当三个应用程序共 同运行时,他们将会占用 12MB 的虚拟内存。问题还远不于此。一旦类库厂商发现 CMath 类库有一个缺陷后,发布一个新的类库,此时需要要求所 有运用此类库的应用程序。此外别无他法了。
w
页码,1/15(W)
::首页 >> 文档中心 >> 在线杂志 >> COM技术(COM/DCOM/COM+)
[ 在线杂志 第 26期 ]
[ 原创文档 本文适合中级读者 已阅读 108307 次 ]
文档
COM 技术初探(一) 作者 : venture
下载源代码 目录
一. COM是一个更好的 C++
http://www.vckbase.com/document/viewdoc/?id=915
http://www.vckbase.com/document/viewdoc/?id=915
2010/4/20
w
页码,8/15(W)
{ 0x7c8027ea, 0xa4ed, 0x467c, { 0xb1, 0x7e, 0x1b, 0x51, 0xce, 0x74, 0xaf, 0x57 } }; //{CA3B37EA-E44A-49b8-9729-6E9222CAE84F} static const GUID IID_IAdvancedMath = { 0xca3b37ea, 0xe44a, 0x49b8, { 0x97, 0x29, 0x6e, 0x92, 0x22, 0xca, 0xe8, 0x4f } }; interface ISimpleMath : public IUnknown { public: virtual int Add(int nOp1, int nOp2) = 0; virtual int Subtract(int nOp1, int nOp2) = 0; virtual int Multiply(int nOp1, int nOp2) = 0; virtual int Divide(int nOp1, int nOp2) = 0; }; interface IAdvancedMath : public IUnknown { public: virtual int Factorial(int nOp1) = 0; virtual int Fabonacci(int nOp1) = 0; }; #endif 此文件首先 #include <unknwn.h> 将 IUnknown 接口定义文件包括进来。 接下来定义了两个接口, GUID ( Globally Unique Identifier 全局唯一标识符)它能保证时间及空间上的唯一。 ISmipleMath 接口里定义了四个方法,而 IAdvancedMath 接口里定义了二个方法。这些方法都是虚函数,而整个 ISmipleMath 与 IAdvancedMath 抽象类就作为二进制的接口。
页码,6/15(W)
每个标准的 COM 组件都需要一个接口定义文件,文件的扩展名为IDL。让我们看 IUnknow 接口的定义文件是怎样的。 [ local, object, uuid(00000000-0000-0000-C000-000000000046), pointer_default(unique) ] interface IUnknown { typedef [unique] IUnknown *LPUNKNOWN; cpp_quote("//////////////////////////////////////////////////////////////////") cpp_quote("// IID_IUnknown and all other system IIDs are provided in UUID.LIB") cpp_quote("// Link that library in with your proxies, clients and servers") cpp_quote("//////////////////////////////////////////////////////////////////") HRESULT QueryInterface( [in] REFIID riid, [out, iid_is(riid)] void **ppvObject); ULONG AddRef(); ULONG Release(); } [local] 属性禁止产生网络代码。 [object] 属性是表明定义的是一个 COM 接口,而不是 DEC 风格的接口。 [uuid] 属性给接口一个 GUID 。 [unique] 属性表明 null( 空 ) 指针为一个合法的参数值。 [pointer_defaul] 属性所有的 内嵌指针 指定一个默认指针属性 typedef [unique] IUnknown *LPUNKNOWN; 这是一个类型定义 cpp_quote 这个比较有趣,这是一个在 idl 文件写注解的方法。这些注解将保存到 ***.h 和 ***_i.c 文件中 [in] 表示这个参数是入参 [out] 表示这个参数是出参 [iid_is(riid)] 表示这个参数需要前一个的 riid 参数。
二、 COM 基础 1 、 CO M 基本知 识 1.1 返回值 HRESULT
http://www.vckbase.com/document/viewdoc/?id=915
2010/4/20
w
页码,5/15(W)
COM 要求所有的方法都会返回一个 HRESULT 类型的错误号。 HRESULT 其实就一个类型定义: typedef LONG HRESULT; 有关 HRESULT 的定义见 winerror.h 文件 // // // // // // // // // // // // // // // // // // // // Values are 32 bit values layed out as follows: 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 +-+----+-------------------------+---------------------------------+ |S| Res| Facility | Code | +-+----+-------------------------+---------------------------------+ where S - is the severity code 0 - Success 1 - Error Res- is a reserved bit Facility - is the facility code Code - is the facility''s status code
我们一般下面的宏来判断方法是否成功:
#define SUCCEEDED(hr)(long(hr)>=0) #define FAILED(hr)(long(hr)<0)
1.2 初识 IDL
http://www.vckbase.com/document/viewdoc/?id=915
2010/4/20
w
2010/4/20
w
页码,2/15(W)
1. COM 是什么 2. 从 C++ 到 DLL 再到 COM 2.1 C++ 2.2 DLL 2.3 COM 二. COM基础 1. COM基本知识 1.1 返回值HRESULT 1.2 初识idl 1.3 IUnkown接口 2. 一个比较简单的COM 2.1 interface.h文件 2.2 math.h文件 2.3 math.cpp文件 2.4 simple.cpp文件 2.5 Math组件的二进制结构图 2.6 小结
2 、一个比较简单的 COM
此例子共有四个文件组成: 文件名 Interface.h Math.h 和 Math.cpp Simple.cpp 主函数文件
2ຫໍສະໝຸດ Baidu1 interface. h 文件
说明 接口类定义文件 实现类文件 这里用来当作 COM 的客户端
#ifndef INTERFACE_H #define INTERFACE_H #include <unknwn.h> //{7C8027EA-A4ED-467c-B17E-1B51CE74AF57} static const GUID IID_ISimpleMath =
相关文档
最新文档