荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: oopilix (冬眠的抽象实例), 信区: Visual
标  题: [zz]《COM技术内幕》学习笔记(2)
发信站: 荔园晨风BBS站 (Mon Oct 20 13:26:45 2003), 站内信件

原作者姓名 雷神
文章原始出处 http://www.ai361.com

介绍
生命是从一个addref开始的,直到release结束,你没有办法回避生命的规律,如
果你不想要release,又可能你会提早预见一个exception,在生命的表现上就会是
祸端;如果你想要再耍点小聪明,来个死循环,那么你就会为你的循环浪费更多的
时间,因为生命的运动只能向前。

读者评分 3 评分次数 1

正文
这是第二部分,包括第4章到第6章。

生命是一个COM组件(原封未动转自UMLCHINA)
*原文*(*sslxml*于2001/07/30 16:30粘贴) *生命是一个COM组件*
自从每个生命的初期,她就是一个COM组件,上帝通过地球这个操作系统调度生命
,而各个生命也在被调度的时候完成了自己的生老病死的循环。
每个COM组件都是给系统中其它部分提供服务的,并且由于接口的多样性,在不同
的方向上看,每个COM组件提供的服务都很专。
COM组件间是需要紧密联接的,缺少了任何一个服务,生命都会不全。
生命是从一个addref开始的,直到release结束,你没有办法回避生命的规律,如
果你不想要release,又可能你会提早预见一个exception,在生命的表现上就会是
祸端;如果你想要再耍点小聪明,来个死循环,那么你就会为你的循环浪费更多的
时间,因为生命的运动只能向前。
生命的开始是一个偶然,生命的尽头是一屡清烟。
写好自己的程序吧,因为,你的组件只能由别人来评判。
生命其实很简单,只是一个COM组件。

怎么样,你能够理解sslxml朋友说的生命是一个COM组件吗?如果能够产生共振,
说明你对组件已经有了一定的认识。

FAQ11:如何控制COM组件的生命周期?〖第四章〗
FAQ12:什么是引用记数?〖第四章〗
FAQ13:使用引用记数的规则是什么?〖第四章〗
FAQ14:什么是动态链接库(DLL)?〖第五章〗
FAQ15:为什么使用动态链接库(DLL)?〖第五章〗
FAQ16:关于HRESULT?〖第六章〗
FAQ17:关于GUID?〖第六章〗
FAQ18:关于注册表?〖第六章〗
FAQ19:关于组件类别?〖第六章〗
FAQ20:关于COM库函数?〖第六章〗

Question:
    如何控制COM组件的生命周期?
Answer:
    IUnKnown的成员函数AddRef和Release的作用提示何时处理完一个接口。
    当使用完所有的接口之后组件可以自己释放自己。
    组件是通过AddRef和Release实现引用记数的内存管理技术。
Question:
    什么是引用记数?
Answer:
    引用记数是使组件自行决定将自己删除的最简单的也是效率最高的方法。
    COM组件将维护一个称为引用记数的数值。
    当客户从组件获得一个接口时,引用记数值加1。
    当客户使用完一个接口时,引用记数值减1。
    当引用记数值为0时,组件将自己从内存中删除。
    当客户对已有的接口创建另外一个引用时,也会增加引用记数值。
    AddRef用来增加引用记数值,Release用来减少引用记数值。
Question:
    使用引用记数的规则是什么?
Answer:
    对于返回接口指针的函数,在返回之前应该用相应的指针调用AddRef。
    使用完接口后调用Release函数。
    在赋值之后调用AddRef。即将一个接口指针赋给另一个接口指针时(建立接口
的另一个引用)。
    对组件的每一个接口分别维护一个引用记数。
    对生命期嵌套在其他接口指针中的指针无需进行引用记数。
    生命周期重叠的接口指针必须分别对这两个借口指针进行引用记数。
    无需对存在于局部变量中的接口指针进行引用记数。
    全局变量或全局变量复制的指针必须进行引用记数。
    输出参数返回一个新的接口指针的函数必须调用AddRef。
    传入函数的接口指针无需调用AddRef和Release。
    对任何不能确定的情形都应该调用AddRef和Release对。注意需成对。

Question:
    什么是动态链接库(DLL)?
Answer:
    动态链接库(DLL)只是一个组件服务程序,或者说是发行组件的一种方式。

    组件可以被看成在DLL中实现的接口集。

Question:
    为什么使用动态链接库(DLL)?
Answer:
    原因是DLL可以共享它们所链入的应用程序的地址空间。
    更加详细的解释是:在WINDOWS中,动态链接库与客户使用的是同一个地址空
间,DLL将驻留在所链接的应用程序地址空间中。客户和组件是通过接口进行交互
的。一个接口实际上是一个指向函数的指针列表(vtbl),组件将为vtbl分配内存
,并用每一个函数的地址来初始化此表。为了能够让客户能够访问组件为vtbl分配
的内存。所以要使用动态链接。
    DLL还有一个名字叫进程内服务程序,因为它和应用程序共享一个进程。
    静态链接和动态链接的区别是获取接口指针的方式不同。

Question:
    关于HRESULT?
Answer:
    组件使用HRESULT来向其用户报告各种情况(Here’s the RESULT)。
    HRESULT是一个可以分成三个部分的32位值。
    大部分COM组件的接口函数返回HRESULT。
    HRESULT的比特位表示函数调用是否成功。
    成功的代码有多个。失败的代码也有多个。
    因为客户使用的组件可能会发生变化,所以失败的代码可能会发生变化。
    HRESULT的低16位包含函数的返回代码。
    HRESULT其余的15位包含有关类型和返回值起源的详细信息。这些信息是设备
代码。
我们可以用WIN32 API FormatMessage函数显示标准的COM错误信息。
我们可以用MAKE_ HRESULT宏来自己定义一个HRESULT值。
但是最好使用通用的COM成功和失败代码,避免自己定义。

Question:
    关于GUID?
Answer:
    GUID是组件和接口的标识号。
    GUID不但可以用来唯一的标识接口,还可以用来唯一的标识组件。
    GUID是英文Globally Unique Identifier(全局唯一标识符)的缩写。
    GUID在时间上和空间上都是唯一的。(目前生成GUID的算法可以保证3400年它
仍然可以是唯一的)
    我们可以用VC++带的GUIDGEN程序来生成一个GUID。
在COM中用来标识组件的GUID被称为类标识符。
为了和IID进行区别,类标识符对应的类型是CLSID。
我们可以使用OBJBASE.H中定义的IsEqualGUID、ISEqualIID、IsEqualCLSID来进行
比较。
最后GUID一般采用引用传递。

Question:
    关于注册表?
Answer:
    注册表是一个由许多元素构成的层次结构。
    每一个元素被称为“键”字。
    每一个键可以包含一系子键、一系列命名的值/或一个默认值。
    子键还可以以包含其他子键或值。
    值不能以包含其他子键或值。
    键和值都有相对应的数据类型,大多数情况下它们是字符串。
    COM只使用了注册表的一个分支:HKEY_CLASSES_ROOT,在此键下可以看到一个
CLSID键。
    CLSID键下有所有组件的CLSID。
    CLSID有一个默认值是DLL文件名称的InprocServer32的子键。
    ProgID是程序员给CLSID指定的一个友好的名称。
可以用COM库提供的CLSIDFromProgID和ProgIDFromCLSID进行ProgID和CLSID之间的
转换。
我们可以用REGSVR32程序来注册某个组件。
但通常我们调用DllRegisterServer来进行安装程序时的自注册。
Question:
    关于组件类别?
Answer:
    组件类别是一个接口集合,该集合被分配了一个GUID,此GUID被称为CATID。

    对于某个组件若它实现了某个组件类别的所有接口,那么它就可以注册成为组
件类别的一个成员。
    属于某个组件类别的组件是组件类别的一个特定实现。
    一个组件可以是多个组件类别的成员。
    组件类别的作用是指定一个组件必须实现的接口集合。
    组件类别可以使程序员无需自己完成注册表的处理,这些工作由WINDOWS系统
的组件类别管理器(Component Category Manager)负责。

Question:
    关于COM库函数?
Answer:
    COM定义了一个函数库用来保证组件和客户的一些相同的操作具有标准性和兼
容性。
    函数库是在OLE32.DLL中实现的。静态链接用OLE32.LIB.
    进程必须调用CoInitialize来初始化COM函数库。
    每个进程只需对COM函数库初始化一次,并且在EXE中进行。
    每个CoInitialize需要对应一个CoUninitialize。
    OLE是建立在COM基础上的,对它的初始化应该调用OleInitialize和
OleUninitialize对。




--

※ 来源:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 61.144.235.39]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店