masm32开发com组件介绍[一]

作 者: combojiang
时 间: 2007-12-10,14:09
链 接: http://bbs.pediy.com/showthread.php?t=56328

声明:本贴参考网站:http://ourworld.compuserve.com/ 

[一]基础知识篇
组件对象模型(Com)在windows操作系统中应用越来越广泛。com因为大量的技术细节显得很复杂,但是正是这种复杂才使com组件的调用显得十分简单。 com和使用程序采用server/client架构。下面我们将在后续的两篇中介绍com组件的编写与调用。

com编程时当前程序开发的热点,各种编程语言都为组件编写提供了很好的支持,但是汇编语言例外,汇编语言开发组件没有优势。但是透过汇编开发的了解,可以使我们了解com组件的工作原理。好了,闲话少说,开始介绍:)

所有的inc头文件都要满足如下特点:
  
1) masm32松散的类型定义约定将继续使用。就是说参数可以被定义为他们的基本类型,代表性的如:DWORD

2) 里面不能创建任何的代码,仅仅包含定义信息,头文件里面需要包含代码,则必须定义为宏。
  
3) 结构体应该参照他们的C原形来定义。

4) GUID 结构定义在windows.inc文件中,GUID的值应该通过textequ宏来定义,这样不会直接产生任何代码。

5) 接口定义分为两步:
   1.一个通用的宏产生一个通用的接口结构。
   2.使用接口名字来修饰结构自身的方法名字。
   这种方式可以有效地避免namespace冲突,并且方便接口定义结构继承。
  
6)COM接口函数调用使用coinvoke宏。




GUIDS
EXAMPLE: 

sIID_IUnknown  TEXTEQU  <{000000000H, 00000H, 00000H, /
                            {0C0H, 000H, 000H, 000H, 000H, 000H, 000H, 046H}} 

可以被用来定义
IID_IUnknown   GUID    sIID_IUnknown 



  
接口:
由于MASM32原形约定松散的类型检查,主要检查编译时函数的参数的个数。因此可以非常简单的定义接口函数,如下所示,用下表值来表示函数参数的个数。

comethod1Proto   typedef proto :DWORD 
comethod2Proto   typedef proto :DWORD, :DWORD 
comethod3Proto   typedef proto :DWORD, :DWORD, :DWORD 
comethod4Proto   typedef proto :DWORD, :DWORD, :DWORD, :DWORD 
comethod4Proto   typedef proto :DWORD, :DWORD, :DWORD, :DWORD, :DWORD 

函数指针如下:
comethod1        typedef ptr comethod1Proto 
comethod2        typedef ptr comethod2Proto 
comethod3        typedef ptr comethod3Proto 
comethod4        typedef ptr comethod4Proto 
comethod5        typedef ptr comethod4Proto


IUnknown接口: IUnknown接口是基本接口,其他所有接口都是派生于它。函数原形定义如上,其定义如下:

_vtIUnknown MACRO CastName:REQ 
    ; IUnknown methods 
    &CastName&_QueryInterface comethod3  ? 
    &CastName&_AddRef         comethod1  ? 
    &CastName&_Release        comethod1  ? 
ENDM 

IUnknown                        STRUCT 
    _vtIUnknown IUnknown 
IUnknown                        ENDS

其展开如下: 

IUnknown                        STRUCT 
    IUnknown_QueryInterface comethod3    ? 
    IUnknown_AddRef         comethod1    ? 
    IUnknown_Release        comethod1    ? 
IUnknown                        ENDS


IClassFactory 接口
IClassFactory派生于 IUnknown.它的结构开始是 IUnknown 的方法, 后面添加了 2个自己的方法. 

_vtIClassFactory MACRO CastName:REQ 
    ; IUnknown methods  
    _vtIUnknown CastName 
    ; IClassFactory methods 
    &CastName&_CreateInstance comethod4 ? 
    &CastName&_LockServer     comethod2 ? 
ENDM 
  
IClassFactory                   STRUCT 
    _vtIClassFactory IClassFactory 
IClassFactory                   ENDS

展开如下: 

IClassFactory                   STRUCT 
    IClassFactory_QueryInterface comethod3 ? 
    IClassFactory_AddRef         comethod1 ? 
    IClassFactory_Release        comethod1 ? 
    IClassFactory_CreateInstance comethod4 ? 
    IClassFactory_LockServer     comethod2 ? 
IClassFactory                   ENDS


Coinvoke宏

;---------------------------------------------------------------------
; coinvoke MACRO 
; pInterface    pointer to a specific interface instance
; Interface     the Interface's struct typedef
; Function      which function or method of the interface to perform
; args          all required arguments 
;                   (type, kind and count determined by the function)
;
coinvoke MACRO pInterface:REQ, Interface:REQ, Function:REQ, args:VARARG
    LOCAL istatement, arg
    FOR arg, <args>     ;; run thru args to see if edx is lurking in there
        IFIDNI <&arg>, <edx>
            .ERR <edx is not allowed as a coinvoke parameter>
        ENDIF
    ENDM
    istatement CATSTR <invoke (Interface PTR[edx]).&Interface>,<_>,<&Function, pInterface>
    IFNB <args>     ;; add the list of parameter arguments if any
        istatement CATSTR istatement, <, >, <&args> 
    ENDIF 
    mov edx, pInterface
    mov edx, [edx]
    istatement
ENDM
;---------------------------------------------------------------------
例如:QueryInterface方法调用如下:

coinvoke ppv ,IUnknown, QueryInterface, ADDR IID_SomeOtherInterface, 
ADDR ppnew


HRESULTS
任何一个com接口函数的返回值类型都是一个hResult, 4个字节长。返回值在eax寄存器中。可以用这个值来判断函数调用是否成功。

.IF !SIGN? 
; function passed 
.ELSE 
; function failed 
.ENDIF
接下来,我们定义了宏来简化它: 
.IF SUCCEEDED   ; TRUE if SIGN bit not set
.IF FAILED     ; TRUE is SIGN bit set


结论:

以上这些是你用汇编开发com需要用到的,这些适用于activex的开发。 

你可能感兴趣的:(编程,汇编,function,语言,interface,程序开发)