序:
近期为了实现Flash容器,实现一些特定的功能,查找了相关的资料,摘录一下
Windows 对象以其所具有的特别功能而存在着。但如何能得到该对象的指针呢?
只能通过接口对 Windows对象进行访问,一个指针仅能访问一个接口, 通常使用一个圆圈表示一个接口
同一对象中存在着不同的接口,可以通过 QueryInterface() 来获得另一接口,因为所有接口都存在该函数
IUnknown 是所有 Windows 对象必须支持的基本接口
COM对象的表示,通常 IUnknown接口位于对象的上方,其它所有对象则位于对象的左面或右面。
C++对象有一定的局限性,因为被程序语言定义的对象将存取访问限制到存在于用户自己进程空间中的对象上。
而 Windows 对象由系统定义,对本机上任一处的对象都开放存取访问,最终甚至可访问其它机器上的对象。
相比C++中的对象,Windows的对象有以下的规则
1. Windows的对象至少支持 IUnknown 的接口
2. 不能像C++那样New操作而得到实例对象,而是通过某些接口来获取该实例对象的指针
3. 不能像C++那样Delete操作来毁灭对象,而是通过Release() 接口来释放
引用计数的规则:
1、任何返回接口指针的函数必须通过该指针调用 AddRef()
2、所有 AddRef() 调用都必须配有 Release() 调用
引用计数可减少到四种特定的规则,其中 AddRef 对一个指针的新的拷贝是必要的(这样,当消除时就必须通过它来进行
Release 调用)
在一个 Out-Parameter 中返回一个新的接口指针或将一个新的接口指针作为一个返回值的函数在返回前通过该指针为对象调用 AddRef
接受了一个 in-out parameter 调用 Release ,并必须为 Out-parameter 调用 AddRef. 这些函数的调用程序必须为过去的指针调用 AddRef 以维护一个分离的拷贝,如果已知该函数是为了该指针调用了Release 的话
如果同一对象的两个指针具有不相关的寿命,则必须为其中的每一个调用 AddRef
必须为一个全局指针的一个当地拷贝调用 AddRef
objbase.h
QueryInterface既的所有实现都必须遵循的一些规则,以便客户能够获取关于组件的足够多的知识并对之施实一些控制和其他有用的处理。如果没有这些规则,是不可能编写出组件的,因为在这种情况下,QueryInterface的行为将是不确定的。具体来讲,这些规则是:
QueryInterface返回的总是同一 IUnknown指针。
若客户曾经获取过某个接口,那么它将总能获取此接口。
客户可以再次获取已经拥有的接口。
客户可以返回到起始接口。
若能够从某个接口获取某特定接口,那么可以从任意接口都将可以获取此接口。
COM 规则
http://www.hackhome.com/InfoView/Article_121566_3.html
SCODE
全局唯一标识符
OLE2接口成员使用特定的 cdecl 调用约定
构件对象是一个被唯一的类标识符 clsID 所标识的 windows 对象,它把对象与系统中的某个特定的DLL或EXE文件联系起来
为获得指向一个构件对象的指针,可以把一个别 CLSID 传递给构件对象库 API 函数
复合文档中的概念
载体
服务器
调用OLE API过程
SetMessageQueue(96)
CoBuildVersion() 或 OleBuildVersion
CoInitialize() 或 OleInitialize()
最后,CoUninitialize() 或 OleUninitialize()
注意,CoBuildVersion(), CoInitialize() 与 CoUninitialize()
OleBuildVersion(), OleInitialize() 与 OleUninitialize() 需要一一对应
以 Co 开头的函数控制对构件对象库函数的访问,
如果要使用剪贴板、拖放、复合文档或有关自动执行的API,那么必须使用以 Ole 开头的函数,
以 Ole 开头的函数只不过先进行一些特定的操作,然后调用 Co 开头的函数
复合文档应用程序,包括载体,总是使用Ole开头的函数
每调用一次 XXX Initialize() 都应该有一次相应的 XXX Uninitialize() 调用
注册 CLSID P 165
分类工厂
DLL 服务器
HRESULT __export FAR PASCAL DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID FAR* ppv);
调用 CoCreateInstance / CoGetClassObject 并传递 CLSCTX_INPROC_SERVER 时,会在注册数据库中为已给的 CLSID 寻找 InprocServer 接着调用 CoLoadLibrary 把服务器放入内存,最后调用 GetProcAddress 寻找 DllGetClassObject
DllGetClassObject() 是我们为OLE2 实现的一个接口函数
CoRegisterClassObject()
IClassFactory::LockServer 的锁存计数
OLE2的应用程序既可以实现自己的分配器,也可使用OLE2提供的分配器,该分配器是基于多重局部堆栈技术而作用。
OLE2总是实现一个相似的共享分配器,它可以在应该程序之间提供内存共享
OLE2中对象的复用性是通过称为“包含”和“聚集”的两种机制,而不是通过“继承”来实现
Storage 和 Stream 的两种对象来展示结构化存储的结构
http://www.cit.dk/COT/reports/reports/Case3/02/THESIS/speciale/StructuredStorage.html
一个流相当于一个标准文件,只不过它是通过 IStream 接口展示