我想使用IDispatch的后期绑定技术,即通过传入组件的ClsID,方法的名字,方法的参数集,得到我想要的结果,即使用invoke方法。
对于参数都是const的,我没有问题,现在的问题是,我的组件的很多方法的参数都是var型和out型的,我希望调用时把这些也传出来,请问如何处理?
下面是我写的代码的关键部分,大家看看有什么问题?
procedure TdmSocket.InvokeCall(const AstrClsID, AstrMethodID: WideString;
var AvarParams, AvarResult: OleVariant);
//上面的参数的含义依次是:组件的ClsID,方法的名字,参数数组,结果集数组 procedure GetArgsFromParams( var Args : array of TVariantArg );
//把AvarParams即传入的参数组合传递到TDispParams中去,以备invoke调用
var
lIndex, lHigh : integer ;
varValue : oleVariant ;
begin
lhigh := VarArrayHighBound( AvarParams, 1 );
for lIndex := 0 to lhigh do begin
varValue := AvarParams[lIndex];
if VarType( varValue ) = varInteger then begin
Args[lHigh - lIndex].vt := VT_I4;
Args[lHigh - lIndex].lVal := StrToInt( VarToStr( varValue ));
end
else if ( VarType( varValue ) = varString ) or
( VarType( varValue ) = varOleStr ) then begin
Args[lHigh - lIndex].vt := VT_BSTR;
Args[lHigh - lIndex].bstrVal := PWideChar( WideString( VarToStr( varValue ) ));
end ;
end ;
end ; procedure GetParamsFromArgs( disParams : TDispParams );
//把TDispParams型的参数传回到AvarParams,以便传回给客户端
var
lIndex, lHigh, pArgErr : integer ;
varValue, var2 : oleVariant ;
begin
lhigh := VarArrayHighBound( AvarParams, 1 );
for lIndex := 0 to lhigh do begin
varValue := AvarParams[lIndex];
DispGetParam( disParams, lHigh-lIndex, VT_BSTR, var2, pArgErr);
if var2 <> varValue then begin
AvarParams[lIndex] := var2 ;
end ;
end ;
end ;
var
objUnknown : IDispatch ;
Names : array [0..0] of PWideChar;
disps : array [0..0] of TDispID;
varParams : TDispParams ;
ReturnValue : OleVariant;
arrArgs: array[0..1000] of TVariantArg ;
lRet, lhigh : integer ;
aexception: TExcepInfo;
begin
objUnknown := CreateComobject( StringToGuid( AstrClsID) ) as IDispatch;
Names[0] := StringToOleStr( AstrMethodID );
objUnknown.GetIDsOfNames( GUID_NULL, @Names, 1, LOCALE_SYSTEM_DEFAULT, @disps );
lhigh := VarArrayHighBound( AvarParams, 1 );
GetArgsFromParams( arrArgs );
varParams.rgvarg := @arrArgs ;
varParams.rgdispidNamedArgs := nil;
varParams.cNamedArgs := 0;
varParams.cArgs := lHigh + 1; lRet := objUnknown.Invoke( disps[0], GUID_NULL, LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD, varParams, @ReturnValue, @aexception, nil ); if lRet <> 0 then begin
raise Exception.Create( IntToStr( lRet ) + ';' +
String( aexception.bstrSource ) );
end
else begin
AvarResult := ReturnValue;
GetParamsFromArgs( varParams );
end ;
end;
在有var或out型参数的时候就会报错请高手指教,如有可能请提供资料参考
对于参数都是const的,我没有问题,现在的问题是,我的组件的很多方法的参数都是var型和out型的,我希望调用时把这些也传出来,请问如何处理?
下面是我写的代码的关键部分,大家看看有什么问题?
procedure TdmSocket.InvokeCall(const AstrClsID, AstrMethodID: WideString;
var AvarParams, AvarResult: OleVariant);
//上面的参数的含义依次是:组件的ClsID,方法的名字,参数数组,结果集数组 procedure GetArgsFromParams( var Args : array of TVariantArg );
//把AvarParams即传入的参数组合传递到TDispParams中去,以备invoke调用
var
lIndex, lHigh : integer ;
varValue : oleVariant ;
begin
lhigh := VarArrayHighBound( AvarParams, 1 );
for lIndex := 0 to lhigh do begin
varValue := AvarParams[lIndex];
if VarType( varValue ) = varInteger then begin
Args[lHigh - lIndex].vt := VT_I4;
Args[lHigh - lIndex].lVal := StrToInt( VarToStr( varValue ));
end
else if ( VarType( varValue ) = varString ) or
( VarType( varValue ) = varOleStr ) then begin
Args[lHigh - lIndex].vt := VT_BSTR;
Args[lHigh - lIndex].bstrVal := PWideChar( WideString( VarToStr( varValue ) ));
end ;
end ;
end ; procedure GetParamsFromArgs( disParams : TDispParams );
//把TDispParams型的参数传回到AvarParams,以便传回给客户端
var
lIndex, lHigh, pArgErr : integer ;
varValue, var2 : oleVariant ;
begin
lhigh := VarArrayHighBound( AvarParams, 1 );
for lIndex := 0 to lhigh do begin
varValue := AvarParams[lIndex];
DispGetParam( disParams, lHigh-lIndex, VT_BSTR, var2, pArgErr);
if var2 <> varValue then begin
AvarParams[lIndex] := var2 ;
end ;
end ;
end ;
var
objUnknown : IDispatch ;
Names : array [0..0] of PWideChar;
disps : array [0..0] of TDispID;
varParams : TDispParams ;
ReturnValue : OleVariant;
arrArgs: array[0..1000] of TVariantArg ;
lRet, lhigh : integer ;
aexception: TExcepInfo;
begin
objUnknown := CreateComobject( StringToGuid( AstrClsID) ) as IDispatch;
Names[0] := StringToOleStr( AstrMethodID );
objUnknown.GetIDsOfNames( GUID_NULL, @Names, 1, LOCALE_SYSTEM_DEFAULT, @disps );
lhigh := VarArrayHighBound( AvarParams, 1 );
GetArgsFromParams( arrArgs );
varParams.rgvarg := @arrArgs ;
varParams.rgdispidNamedArgs := nil;
varParams.cNamedArgs := 0;
varParams.cArgs := lHigh + 1; lRet := objUnknown.Invoke( disps[0], GUID_NULL, LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD, varParams, @ReturnValue, @aexception, nil ); if lRet <> 0 then begin
raise Exception.Create( IntToStr( lRet ) + ';' +
String( aexception.bstrSource ) );
end
else begin
AvarResult := ReturnValue;
GetParamsFromArgs( varParams );
end ;
end;
在有var或out型参数的时候就会报错请高手指教,如有可能请提供资料参考
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货