我自己记录的COM原理及应用学习笔记。
● CoCreateGuid(GUID * pGuid); 创建GUID API.
● 包容,聚和
● _cdecl: C函数格式,调用函数从右到左压入栈,由调用函数弹出栈,由调用函数恢复栈.
_stdcall: COM调用习惯.一般还要在前冠上 extern "C" .
__stdcall 函数的参数被从右到左推送到堆栈上,被调用函数在返回之前从堆栈中弹出这些参数。
对于 C,__stdcall 命名约定使用以下划线 ( _ ) 开头的函数名,后跟“at”符 (@) 和函数参数大小(以字节为单位)。不执行任何大小写转换。
● COM对象的接口原则:
1 对于同一个对象的不同接口指针,查询得到的 IUnknown 接口必须完全相同.
2 接口对称性.对一个接口查询其自身总应该成功.
3 接口自反性.如果一个接口指针查询到另一个接口指针,则从第二个接口指针再回到第一个接口指针必定成功.
4 接口传递性.如果第一个接口指针查询到第二个接口指针,从第二个接口指针可以到第三个接口指针,则从第三个接口指针一定可以查询到第一个接口指针.
4.5 接口查询时间无关性.
● 实现多接口 COM 对象有两种方法,一是使用多重继承,另一种是使用内嵌类成员.
● 编制 DLL 程序的一般步骤:
1. 创建一个 DLL 工程.
2. 对每个引出函数,使用 extern "C" 说明符,以及 _stdcall 修饰符.
3. 按照传统的编程方法,我们还应该编写一个 DEF 文件,用来描述 DLL 程序的模块信息.在 Win32 平台上,我们可以不使用DEF文件,而是直接在函数说明时使用 _declspec(dllexport) 说明符.如:
extern "C" _declspec(dllexprot) int _stdcall MyFunction(int n);
● 三个系统函数可用于操作 DLL 程序.
LoadLibrary 装载 DLL模块函数.
GetProcAddress 取出函数地址.
FreeLibrary 释放程序函数.
● 对 Dll 的三点说明.
1. Dll程序可以引出函数,及全局变量.引出全局变量的方法有二个,一是把变量名放到 DEF 文件的 EXPORTS 部分,并加上 DATA 选项;二是在变量说明前加上 _declspec(dllexprot) 说明符.
2. VC++ 提供了 DumpBin ,通过 /Exports 选项可以列出 Dll 程序中的所有被引出的信息.
3. 客户程序本身也可以是一个 Dll 程序,如果它被装入进程空间中,以便可以调用系统函数操作服务程序 Dll 模块.
4. Dll 中的组件严重错误可能引起客户进程的崩溃.
● 进程外通讯方式:
1. DDE 动态数据交换.
2. 命名管道 named pipe
3. 共享内存.
4. COM 采用本地过程调用(Local procedure call,LPC)和远程调用的方法进行进程间通信.
● 一个 COM 对象有唯一标识符(CLSID)和程序标识符(ProgID).两个转换函数:
1. CLSIDFromProgID
1. ProgIDFromCLSID
● 进程内组件注册:
RegSvr32 file.dll RegSvr32调用组件程序的 DllRegisterServer 函数.
RegSvr32 file.dll RegSvr32调用组件程序的 DllUnregisterServer 函数.
进程外组件程序注册:COM规范规定,支持自注册的进程外组件必须支持两个命令参数 /RegServer 和 /UnregServer ,参数大小写无关, 而且"/"可以用"-"替代.
● COM库中,三个函数可创建对象:
CoGetClassObject(const CLSID& clsid,DWORD dwClsContext,COSERVERINFO * pServerInfo,const IID& iid,(void **) ppv);
CoGetClasObject 函数先找到由 clsid 指定的 COM 类的类厂,然后连接到类厂对象
如果是进程内组件.GoGetClassObject调用 Dll 模块的 DllGetClassObject 引出函数,并传递 clsid,iid,ppv参数,由 DllGetClassObject 创建类厂并返回类厂对象接口指针.
如果是进程外组件.CoGetClassObject 函数启动组件进程,组件进程把它支持的COM类对象的类厂注册到 COM 中,CoGetClassObject 函数把COM中相应的类厂信息返回.因此,组件外进程被COM库启动时,它必须把所支持的COM类的类厂对象通过 CoRegisterClassObject 函数注册到 COM 中,以便 COM 库创建 COM 对象使用.当进程退出时,必须调用 CoRevokeClassObject 函数以便通知 COM 它所注册的类厂对象不再有效.
CoCreateInstance(const CLSID& clsid,IUnknown * pUnknownOuter,DWORD dwClsContext,const IID& iid,(void **)ppv);
在它内部也调用了 CoGetClassObject .它不能创建远程对象.它首先利用 CoGetClassObject 函数创建类厂对象,然后用得到的对象的接口指针创建真正的COM对象,最后把类厂对象释放并返回.
CoCreateInstanceEx
● 用下面的原则选择创建对象的函数.
1. 如果创建远程对象或希望一次获取对象的多个接口指针,则选用 CoCreateInstanceEx 函数.
2. 如果我们获取类厂对象或要调用类厂的某些成员函数,则选用 CoGetClassObject 函数.
3. 用 CoCreateInstance 函数创建对象,是我们最常用的方法.
● 名词解释:
聚合:
内聚:
连接点:
双重接口:
●
1. 用VC开发的函数中,返回值为 VARIANT* ,在VB中识别错误,识别为 不返回值 .但是 C# 中,能正确识别为 object.
2. 每一个 COM 接口至少有两个属性: object 和 uuid
3. ● 一个顶层指针总是被假定为一个 ref 指针
● 一个仅为输出的顶层指针必须为一个 ref 指针.
● 所有嵌入式的指针,在默认情况下,都被认为是 unique 的.在实际情况下,最好是显式的为嵌入式指针指定属性.事实上,IDL 用 pointer_default 来为所有的嵌入式指针指定默认的指针属性.
● ptr属性称为完全(full)指针.指明这个列集程序的逻辑将检查重复的指针.
●
●
●
●
●
|
作者:NewSea 出处:http://newsea.cnblogs.com/
QQ,MSN:iamnewsea@hotmail.com 如无特别标记说明,均为NewSea原创,版权私有,翻载必纠。欢迎交流,转载,但要在页面明显位置给出原文连接。谢谢。 |

浙公网安备 33010602011771号