标 题: 【原创】masm32开发com组件介绍[一][二][三]
作 者: combojiang
时 间: 2007-12-10,14:09:39
链 接: 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宏。
01 GUIDS
02 EXAMPLE:
03 sIID_IUnknown TEXTEQU <{000000000H, 00000H, 00000H, \
04 {0C0H, 000H, 000H, 000H, 000H, 000H, 000H, 046H}}
05 ;可以被用来定义
06 IID_IUnknown GUID sIID_IUnknown
07 ;接口:
08 ;由于MASM32原形约定松散的类型检查,主要检查编译时函数的参数的个数。因此可以非常简单的定义接口函数,如下所示,用下表值来表示函数参数的个数。
09 comethod1Proto typedef proto : DWORD
10 comethod2Proto typedef proto : DWORD , : DWORD
11 comethod3Proto typedef proto : DWORD , : DWORD , : DWORD
12 comethod4Proto typedef proto : DWORD , : DWORD , : DWORD , : DWORD
13 comethod4Proto typedef proto : DWORD , : DWORD , : DWORD , : DWORD , : DWORD
14 ;函数指针如下:
15 comethod1 typedef ptr comethod1Proto
16 comethod2 typedef ptr comethod2Proto
17 comethod3 typedef ptr comethod3Proto
18 comethod4 typedef ptr comethod4Proto
19 comethod5 typedef ptr comethod4Proto
20 ;IUnknown接口: IUnknown接口是基本接口,其他所有接口都是派生于它。函数原形定义如上,其定义如下:
21 _vtIUnknown MACRO CastName:REQ
22 ; IUnknown methods
23 &CastName&_QueryInterface comethod3 ?
24 &CastName&_AddRef comethod1 ?
25 &CastName&_Release comethod1 ?
26 ENDM
27 IUnknown STRUCT
28 _vtIUnknown IUnknown
29 IUnknown ENDS
30 ;其展开如下:
31 IUnknown STRUCT
32 IUnknown_QueryInterface comethod3 ?
33 IUnknown_AddRef comethod1 ?
34 IUnknown_Release comethod1 ?
35 IUnknown ENDS
36 ;IClassFactory 接口
37 ;IClassFactory派生于 IUnknown.它的结构开始是 IUnknown 的方法, 后面添加了 2个自己的方法.
38 _vtIClassFactory MACRO CastName:REQ
39 ; IUnknown methods
40 _vtIUnknown CastName
41 ; IClassFactory methods
42 &CastName&_CreateInstance comethod4 ?
43 &CastName&_LockServer comethod2 ?
44 ENDM
45 IClassFactory STRUCT
46 _vtIClassFactory IClassFactory
47 IClassFactory ENDS
48 ;展开如下:
49 IClassFactory STRUCT
50 IClassFactory_QueryInterface comethod3 ?
51 IClassFactory_AddRef comethod1 ?
52 IClassFactory_Release comethod1 ?
53 IClassFactory_CreateInstance comethod4 ?
54 IClassFactory_LockServer comethod2 ?
55 IClassFactory ENDS
56 ;Coinvoke宏
57 ;———————————————————————
58 ; coinvoke MACRO
59 ; pInterface pointer to a specific interface instance
60 ; Interface the Interface’s struct typedef
61 ; Function which function or method of the interface to perform
62 ; args all required arguments
63 ; (type, kind and count determined by the function)
64 ;
65 coinvoke MACRO pInterface:REQ, Interface:REQ, Function:REQ, args:VARARG
66 LOCAL istatement, arg
67 FOR arg, <args> ;; run thru args to see if edx is lurking in there
68 IFIDNI <&arg>, < edx >
69 .ERR < edx is not allowed as a coinvoke parameter>
70 ENDIF
71 ENDM
72 istatement CATSTR < invoke (Interface PTR [ edx ]).&Interface>,<_>,<&Function, pInterface>
73 IFNB <args> ;; add the list of parameter arguments if any
74 istatement CATSTR istatement, <, >, <&args>
75 ENDIF
76 mov edx , pInterface
77 mov edx , [ edx ]
78 istatement
79 ENDM
80 ;———————————————————————
81 ;例如:QueryInterface方法调用如下:
82 coinvoke ppv ,IUnknown, QueryInterface, ADDR IID_SomeOtherInterface,
83 ADDR ppnew
84 HRESULTS
85 ;任何一个com接口函数的返回值类型都是一个hResult, 4个字节长。返回值在eax寄存器中。可以用这个值来判断函数调用是否成功。
86 .IF !SIGN?
87 ; function passed
88 .ELSE
89 ; function failed
90 .ENDIF
91 ;接下来,我们定义了宏来简化它:
92 .IF SUCCEEDED ; TRUE if SIGN bit not set
93 .IF FAILED ; TRUE is SIGN bit set
结论:
以上这些是你用汇编开发com需要用到的,这些适用于activex的开发。
作 者: combojiang
时 间: 2007-12-10,14:09:39
链 接: 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宏。
01 GUIDS
02 EXAMPLE:
03 sIID_IUnknown TEXTEQU <{000000000H, 00000H, 00000H, \
04 {0C0H, 000H, 000H, 000H, 000H, 000H, 000H, 046H}}
05 ;可以被用来定义
06 IID_IUnknown GUID sIID_IUnknown
07 ;接口:
08 ;由于MASM32原形约定松散的类型检查,主要检查编译时函数的参数的个数。因此可以非常简单的定义接口函数,如下所示,用下表值来表示函数参数的个数。
09 comethod1Proto typedef proto : DWORD
10 comethod2Proto typedef proto : DWORD , : DWORD
11 comethod3Proto typedef proto : DWORD , : DWORD , : DWORD
12 comethod4Proto typedef proto : DWORD , : DWORD , : DWORD , : DWORD
13 comethod4Proto typedef proto : DWORD , : DWORD , : DWORD , : DWORD , : DWORD
14 ;函数指针如下:
15 comethod1 typedef ptr comethod1Proto
16 comethod2 typedef ptr comethod2Proto
17 comethod3 typedef ptr comethod3Proto
18 comethod4 typedef ptr comethod4Proto
19 comethod5 typedef ptr comethod4Proto
20 ;IUnknown接口: IUnknown接口是基本接口,其他所有接口都是派生于它。函数原形定义如上,其定义如下:
21 _vtIUnknown MACRO CastName:REQ
22 ; IUnknown methods
23 &CastName&_QueryInterface comethod3 ?
24 &CastName&_AddRef comethod1 ?
25 &CastName&_Release comethod1 ?
26 ENDM
27 IUnknown STRUCT
28 _vtIUnknown IUnknown
29 IUnknown ENDS
30 ;其展开如下:
31 IUnknown STRUCT
32 IUnknown_QueryInterface comethod3 ?
33 IUnknown_AddRef comethod1 ?
34 IUnknown_Release comethod1 ?
35 IUnknown ENDS
36 ;IClassFactory 接口
37 ;IClassFactory派生于 IUnknown.它的结构开始是 IUnknown 的方法, 后面添加了 2个自己的方法.
38 _vtIClassFactory MACRO CastName:REQ
39 ; IUnknown methods
40 _vtIUnknown CastName
41 ; IClassFactory methods
42 &CastName&_CreateInstance comethod4 ?
43 &CastName&_LockServer comethod2 ?
44 ENDM
45 IClassFactory STRUCT
46 _vtIClassFactory IClassFactory
47 IClassFactory ENDS
48 ;展开如下:
49 IClassFactory STRUCT
50 IClassFactory_QueryInterface comethod3 ?
51 IClassFactory_AddRef comethod1 ?
52 IClassFactory_Release comethod1 ?
53 IClassFactory_CreateInstance comethod4 ?
54 IClassFactory_LockServer comethod2 ?
55 IClassFactory ENDS
56 ;Coinvoke宏
57 ;———————————————————————
58 ; coinvoke MACRO
59 ; pInterface pointer to a specific interface instance
60 ; Interface the Interface’s struct typedef
61 ; Function which function or method of the interface to perform
62 ; args all required arguments
63 ; (type, kind and count determined by the function)
64 ;
65 coinvoke MACRO pInterface:REQ, Interface:REQ, Function:REQ, args:VARARG
66 LOCAL istatement, arg
67 FOR arg, <args> ;; run thru args to see if edx is lurking in there
68 IFIDNI <&arg>, < edx >
69 .ERR < edx is not allowed as a coinvoke parameter>
70 ENDIF
71 ENDM
72 istatement CATSTR < invoke (Interface PTR [ edx ]).&Interface>,<_>,<&Function, pInterface>
73 IFNB <args> ;; add the list of parameter arguments if any
74 istatement CATSTR istatement, <, >, <&args>
75 ENDIF
76 mov edx , pInterface
77 mov edx , [ edx ]
78 istatement
79 ENDM
80 ;———————————————————————
81 ;例如:QueryInterface方法调用如下:
82 coinvoke ppv ,IUnknown, QueryInterface, ADDR IID_SomeOtherInterface,
83 ADDR ppnew
84 HRESULTS
85 ;任何一个com接口函数的返回值类型都是一个hResult, 4个字节长。返回值在eax寄存器中。可以用这个值来判断函数调用是否成功。
86 .IF !SIGN?
87 ; function passed
88 .ELSE
89 ; function failed
90 .ENDIF
91 ;接下来,我们定义了宏来简化它:
92 .IF SUCCEEDED ; TRUE if SIGN bit not set
93 .IF FAILED ; TRUE is SIGN bit set
结论:
以上这些是你用汇编开发com需要用到的,这些适用于activex的开发。