赞
踩
今天又快速浏览一遍杨老师的COM组件设计与应用18篇,对杨老师的敬仰之情越发强烈,语言流畅、风趣幽默,问题深入浅出的讲的很清楚。更难得的是,看到了字里行间一个技术人员快乐、谦逊的人生态度。
1 COM的起源 复合文件
复合文件 像文件系统一样进行管理的文件 根存储-》子存储-》流
能够进行复合文件操作的主要有三类函数, Win API IStorage接口函数 IStream接口函数
文中包含对复合文件的创建、读取的源码,不详细分析了
引用杨老师的一句话 复合文件,结构化存储,是微软组件思想的起源,在此基础上继续发展出了持续性、命名、ActiveX、对象嵌入、现场激活......一系列的新技术、新概念。
观后:杨老师站在一个比较高的层次上来看COM,嗯,其实是有道理的,结构化存储的好处一是因为有
统一的接口标准,大家方便调用,二是可以通过一个好的机制减少存储空间
2 GUID 和接口
看一下CLSID的定义吧
typedef struct _GUID {
DWORD Data1; // 随机数
WORD Data2; // 和时间相关
WORD Data3; // 和时间相关
BYTE Data4[8]; // 和网卡MAC相关
} GUID;
typedef GUID CLSID; // 组件ID
typedef GUID IID; // 接口ID
16个字节的结构体,唯一标识一个COM组件,IID标识一个接口,和CLSID有着同样的结构
另外还可以用ProgID来标识一个COM组件,并提供CLSID和ProgID之间的相互转换
接口实际就是一个不含数据成员的抽象基类,提供了一些标准的虚函数
COM组件由于用了这样的虚表结构,具有可以跨语言、接口之间传递的特性
因为能够跨语言,所以不提供头文件声明,而是提供tlb文件,每个IDE会根据tlb生成自己能够
解析的包
3 数据类型
HRESULT
由于COM函数调用会在别的进程甚至是别的计算机上运行,因此有必要得到函数执行的结果,HRESULT实际上是一个DWORD类型的数据,用来表示函数执行的结果
Unicode
这个不用说了都知道吧
BSTR
字符串用的是Unicode编码,在字符串前面有4个字节表示该字符串的长度
类型转换函数
之前要加上USES_CONVERSION宏
VARIANT 用做跨语言平台
有一个vt和一个union构成的一个结构体
vt表示数据的类型,union为数据,
在我碰到过的一个程序中,与JSP交互的invoke函数就是用的这种数据类型
4 COM客户端的简单调用
远程COM调用,是通过客户端的代理(Proxy)和服务端的存根(Stub)之间的通信来实现的,具体含义暂时不深究了。
需要调用Release和Addref的情况,引出了智能指针。
COM组件内的内存的申请与释放函数,CoTaskMemAlloc CoTaskMemFree,惭愧啊,这两个函数我都没用到过,文中还提到,但组件如果需要与客户进行内存的交互,则必须使用上表中的后三类函数族,这个不知道原因。
一共举了4个COM调用的例子,前三个不是COM的标准调用,分别是通过CoGetMalloc、SHGetMalloc、CreateStreamOnHGlobal、OleLoadPicture这四个函数得到接口指针的,而最后一个调用快捷方式的
COM组件,用的是COM的标准调用,CoCreateInstance的一套函数
5 用ATL建立第一个组件
由于都是步骤性的描述,就没有什么好说了
a.建立一个ATL的project
b.建立一个ATL的组件
建立一个Simple Object,会继承一个和Class name相同名字的一个接口
给COM设置属性
摘取关于Apartment的一段话,大家都选 Apartment,它代表什么那?简单地说:当在线程中调用组件函数的时候,这些调用会排队进行。因此,这种模式下,我们可以暂时不用考虑同步的问题
c.给接口增加函数
客户端
include .h 和 .c文件,然后按照标准COM调用方式 CoInitialize CoCreateInstance...一路调用。
6 第5篇的.net版
7 编译、注册、调用
a.编译
如果需要使用ATL的最小依赖,预编译头文件中删除ATL_DLL ATL_MIN_CRT
.cpp和.sr文件的编译与其他相仿
.idl文件经过MIDL编译器后,生成tlb文件、.h、.c文件以及代理/存根源程序
b.注册
用ATL生成的COM组件编译时自动注册
Tools/Register Control可用来注册
怎样在安装程序中进行注册呢,这个是一个实际要遇到的问题
找到dll,loadlibrary,然后找到dllregisterserver函数,调用之
但是我看到dllRegisterServer函数一般都没有实现,怎么会进行注册呢,不解
c 调用
最常用的两种客户端调用方式
#include .h .c文件
#import tlb文件,VC会产生包装类,然后调用
d.智能指针
能够自动进行增加引用和减少引用
CComPtr
CComQIPtr 能够给它赋予一个不同的指针类型,会自动调用querryinterface
8 增加接口
这个简单,主要修改了四处,在idl文件中,增加了接口的定义,coclass中增加了添加的接口
com对象增加了对该接口的继承,begin_com_map中增加了接口entry
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。