1 简介
- 自动化对象: 实现了IDispatch接口的COM对象
- 属性: 自动化对象的数据特征
- 方法: 指自动化对象所提供的功能服务, 可以包含参数
2 类型库 (typelib)
(1) 自动化兼容的数据类型VARIANT
typedef struct tagVARIANT {union {struct __tagVARIANT {VARTYPE vt;WORD wReserved1;WORD wReserved2;WORD wReserved3;union {ULONGLONG ullVal; /* VT_UI8 */LONGLONG llVal; /* VT_I8 */LONG lVal; /* VT_I4 */BYTE bVal; /* VT_UI1 */SHORT iVal; /* VT_I2 */FLOAT fltVal; /* VT_R4 */DOUBLE dblVal; /* VT_R8 */VARIANT_BOOL boolVal; /* VT_BOOL */_VARIANT_BOOL bool; /* (obsolete) */SCODE scode; /* VT_ERROR */CY cyVal; /* VT_CY */DATE date; /* VT_DATE */BSTR bstrVal; /* VT_BSTR */IUnknown * punkVal; /* VT_UNKNOWN */IDispatch * pdispVal; /* VT_DISPATCH */SAFEARRAY * parray; /* VT_ARRAY */BYTE * pbVal; /* VT_BYREF|VT_UI1 */SHORT * piVal; /* VT_BYREF|VT_I2 */LONG * plVal; /* VT_BYREF|VT_I4 */LONGLONG * pllVal; /* VT_BYREF|VT_I8 */FLOAT * pfltVal; /* VT_BYREF|VT_R4 */DOUBLE * pdblVal; /* VT_BYREF|VT_R8 */VARIANT_BOOL *pboolVal; /* VT_BYREF|VT_BOOL */_VARIANT_BOOL *pbool; /* (obsolete) */SCODE * pscode; /* VT_BYREF|VT_ERROR */CY * pcyVal; /* VT_BYREF|VT_CY */DATE * pdate; /* VT_BYREF|VT_DATE */BSTR * pbstrVal; /* VT_BYREF|VT_BSTR */IUnknown ** ppunkVal; /* VT_BYREF|VT_UNKNOWN */IDispatch ** ppdispVal; /* VT_BYREF|VT_DISPATCH */SAFEARRAY ** pparray; /* VT_BYREF|VT_ARRAY */VARIANT * pvarVal; /* VT_BYREF|VT_VARIANT */PVOID byref; /* Generic ByRef */CHAR cVal; /* VT_I1 */USHORT uiVal; /* VT_UI2 */ULONG ulVal; /* VT_UI4 */INT intVal; /* VT_INT */UINT uintVal; /* VT_UINT */DECIMAL * pdecVal; /* VT_BYREF|VT_DECIMAL */CHAR * pcVal; /* VT_BYREF|VT_I1 */USHORT * puiVal; /* VT_BYREF|VT_UI2 */ULONG * pulVal; /* VT_BYREF|VT_UI4 */ULONGLONG * pullVal; /* VT_BYREF|VT_UI8 */INT * pintVal; /* VT_BYREF|VT_INT */UINT * puintVal; /* VT_BYREF|VT_UINT */struct __tagBRECORD {PVOID pvRecord;IRecordInfo * pRecInfo;} __VARIANT_NAME_4; /* VT_RECORD */} __VARIANT_NAME_3;} __VARIANT_NAME_2;DECIMAL decVal;} __VARIANT_NAME_1;}VARIANT;
(2) 字符串类型BSTR

OLE提供了一组API函数处理BSTR
SysAllocString、SysAllocStringLen、SysFreeString、SysReAllocString、SysReAllocStringLen以及SysStringLen等
(3) 数组类型SAFEARRAY
(4) 自动化数据类型的转换
- Invoke函数的数据类型转换能力为弱数据类型开发环境提供了极大的便利
- OLE提供了两个类型转换函数:
- VariantChangeType
- VariantChangeTypeEx
OLE也提供了一组专门的类型转换函数Var
From , 比如: - VarR4FromI2
- VarUI2FromDisp等
3 参数传递
其中第四个参数的结构如下IDispatch::Invoke(dispIdMember, // 指定DISPIDlcid, // 指定本地化标识wFlags, // 指示调用类型 DISPATCH_METHOD、DISPATCH_PROPERTYGET、DISPATCH_PROPERTYPUT、 DISPATCH_PROPERTYPUTREFpDispParams, // 包括调用的参数数组、参数的DISPID数组、数组中参数个数等信息pVarResult, // 保存返回值信息puArgErr, // 错误参数的索引值)
typedef struct tagDISPPARAMS{VARIANTARG *rgvarg; // 参数数组, 参数的顺序与客户程序中调用的参数左右顺序刚好相反DISPID *rgdispidNamedArgs; // 参数的分发ID数组UINT cArgs; // 数组中参数个数UINT cNamedArgs; // 命名参数个数} DISPPARAMS;
(1) 参数顺序
例如: Object.Method(arg0, arg1, arg2)
对应Invoke函数的pDispParams参数的DISPPARAMS结构中,cArgs为3
rgarg数组的成员分别为:rgvarg[0]=arg2、rgvarg[1]=arg1、rgvarg[2]=arg0
(2) 可选参数
IDL文件中,可以把方法的参数标记为可选的(optional)
- 可选参数也会出现在DISPPARAMS结构中
- 如果vt域为VT_ERROR并且scode域为DISP_E_PARAMNOTFOUND,则此参数为可选参数
(3) 命名参数
DISPPARAMS结构的cNamedArgs成员指定了在rgarg数组中命名参数的个数, 命名参数可以不受次序约束

