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, // 指定DISPID
lcid, // 指定本地化标识
wFlags, // 指示调用类型 DISPATCH_METHOD、DISPATCH_PROPERTYGET、DISPATCH_PROPERTYPUT、 DISPATCH_PROPERTYPUTREF
pDispParams, // 包括调用的参数数组、参数的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数组中命名参数的个数, 命名参数可以不受次序约束