我自己记录的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)指针.指明这个列集程序的逻辑将检查重复的指针.
  
●   
●   
●   
●   

posted @ 2009-03-09 00:55  NewSea  阅读(432)  评论(0)    收藏  举报