解析 Variants





0/5 (0投票)
2001年7月17日

67096

2
解引用和解析 Variants 和 IDispatch
引言
我创建了一个递归函数,用于反引用传入的 VARIANT
([in]) 并解析 IDispatch
,如果传入的 VARIANT
中包含的变量的类型为 VT_DISPATCH
。
我可以使用 VariantCopy
和/或 VariantCopyInd
,但我希望避免复制数组或其他非预期类型。
请查看我的函数 ResolveVariant()
(如果它很长请见谅),并告诉我您是否发现任何问题。我已经进行了一些测试,没有发现任何问题(包括引用计数)。
HRESULT SomeClass::get_Item(VARIANT Index, VARIANT* pVar) { VARIANT varOut; VariantInit(&varOut); HRESULT hr = ResolveVariant(&Index, &varOut); if (!FAILED( hr ) { switch (varOut.vt) { case VT_BSTR: SomeCodeHere to prepare pVar; break; case VT_I4: SomeCodeHere to prepare pVar; break; default: break; } VariantClear(&varOut); } else return hr; } HRESULT ResolveVariant(VARIANT* pVarIn, VARIANT* pVarOut) { VARIANT* tmpVarIn = pVarIn; ULONG ByRef = 0; while(tmpVarIn->vt == (VT_BYREF | VT_VARIANT) ) tmpVarIn = tmpVarIn->pvarVal; if(tmpVarIn->vt & VT_BYREF) ByRef = VT_BYREF; switch(tmpVarIn->vt) { case (VT_I2): case (VT_BYREF|VT_I2): if(ByRef) { if(!tmpVarIn->piVal) return E_POINTER; pVarOut->iVal = *(tmpVarIn->piVal); } break; case (VT_I4): case (VT_BYREF|VT_I4): if(ByRef) { if(!tmpVarIn->plVal) return E_POINTER; pVarOut->lVal = *(tmpVarIn->plVal); } break; case (VT_BSTR): case (VT_BYREF|VT_BSTR): if(ByRef) { if(!tmpVarIn->pbstrVal) return E_POINTER; if(!*(tmpVarIn->pbstrVal) ) return E_POINTER; pVarOut->bstrVal = *(tmpVarIn->pbstrVal); } break; case (VT_DISPATCH): case (VT_BYREF|VT_DISPATCH): if(ByRef) { if(!tmpVarIn->ppdispVal) return E_POINTER; if(!*(tmpVarIn->ppdispVal) ) return E_POINTER; pVarOut->pdispVal = *(tmpVarIn->ppdispVal); } break; default: return DISP_E_TYPEMISMATCH; } if(ByRef) pVarOut->vt = (tmpVarIn->vt - ByRef); else *pVarOut = *tmpVarIn; if (pVarOut->vt == VT_DISPATCH) { VARIANT varResolved; DISPPARAMS dispParamsNoArgs = {NULL, NULL, 0, 0}; VariantInit(&varResolved); if ( SUCCEEDED pVarOut->pdispVal->Invoke(DISPID_VALUE, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET | DISPATCH_METHOD, &dispParamsNoArgs, &varResolved, NULL, NULL) ) ) { ResolveVariant(&varResolved, pVarOut); } else return E_FAIL; VariantClear(&varResolved); return S_OK; } else { HRESULT hr; VARIANT retVar; VariantInit(&retVar); hr = VariantCopy(&retVar, pVarOut); *pVarOut = retVar; return hr; } }