C
crazycock
Unregistered / Unconfirmed
GUEST, unregistred user!
invoke方法带回返回值的问题
有多个参数传入,需要传出多个结果,所以考虑到使用传一个指针的方法来实现,当然是in proc的前提下。
type
ParamRecord=record
ParamValueArray:array[0..255] of String;
ParamTypeArray:array[0..255] of Integer;
ParamCount:Integer;
ResultValue:String;
ResultType:Integer;
end;
PParamRecord=^ParamRecord;
var
praramRecord; //前面有定义
//------
paramcls:TParamCls;//某个类
HR:HResult;
MyIntf:IDispatch;
MyDispParams: TDispParams;
MyParams: array[0..1] of TVariantArg;
di:TDispID;
begin
......
HR:=OleContainer1.OleObjectInterface.QueryInterface(myGUID,MyIntf);
OleCheck(HR);
// 参数压栈是反序,不过这里只有一个参数,无所谓了。
MyParams[0].vt := VT_UI4;
MyParams[0].ulVal := Cardinal(@pr); //我把指针转成Cardinal,然后在ocx中再用pPR:=Pointer(Value)的方法转回去
with MyDispParams do
begin
rgvarg := @MyParams;
rgdispidNamedArgs := nil;
cArgs := 1;
cNamedArgs := 0;
end;
HR:=MyIntf.GetIDsOfNames(GUID_NULL,@Names,1,0,@di);
OleCheck(HR);
HR:=MyIntf.Invoke(di,GUID_NULL,0,DISPATCH_METHOD,MyDispParams,nil, nil, nil); // (关键位置)
OleCheck(HR);
//更新内存变量的值
paramcls.ParamValue:=pr.ResultValue;
......
end;
============================
ocx中的方法的代码
procedure TafxBaseFunc.func_Add(Value: SYSUINT);
var
pPRParamRecord;
i:Integer;
fSUMouble;
begin //exit; <----
pPR:=Pointer(Value);
try
fSUM:=0;
for i:=0 to pPR.ParamCount-1 do
begin
case pPR.ParamTypeArray of
VT_UINT,VT_INT,VT_I2,VT_I4,VT_R4,VT_R8:fSUM:=fSUM+StrToFloat(pPR.ParamValueArray);
end;
end;
pPR.ResultValue:=FloatToStr(fSUM);
pPR.ResultType:=VT_R8;
except
pPR.ResultValue:='0';
pPR.ResultType:=VT_R8;
end;
end;
经过多个方面的测试,有以下现象和结论:
1。代码能运行,可以得到所需结果,但是平均30秒到1分钟左右,会出现错误,有些错误可以捕捉,有些则直接导致程序关闭;
2。如果把ocx中func_Add的代码屏蔽,即不做运算,则不会有错误出现;
结论:指针访问出现错误。
问题:哪个地方的写法导致了这个错误呢?怎么解决?注:程序中有可能出现临界区的地方都使用了互斥,而且经过检测排除了那种可能。
有多个参数传入,需要传出多个结果,所以考虑到使用传一个指针的方法来实现,当然是in proc的前提下。
type
ParamRecord=record
ParamValueArray:array[0..255] of String;
ParamTypeArray:array[0..255] of Integer;
ParamCount:Integer;
ResultValue:String;
ResultType:Integer;
end;
PParamRecord=^ParamRecord;
var
praramRecord; //前面有定义
//------
paramcls:TParamCls;//某个类
HR:HResult;
MyIntf:IDispatch;
MyDispParams: TDispParams;
MyParams: array[0..1] of TVariantArg;
di:TDispID;
begin
......
HR:=OleContainer1.OleObjectInterface.QueryInterface(myGUID,MyIntf);
OleCheck(HR);
// 参数压栈是反序,不过这里只有一个参数,无所谓了。
MyParams[0].vt := VT_UI4;
MyParams[0].ulVal := Cardinal(@pr); //我把指针转成Cardinal,然后在ocx中再用pPR:=Pointer(Value)的方法转回去
with MyDispParams do
begin
rgvarg := @MyParams;
rgdispidNamedArgs := nil;
cArgs := 1;
cNamedArgs := 0;
end;
HR:=MyIntf.GetIDsOfNames(GUID_NULL,@Names,1,0,@di);
OleCheck(HR);
HR:=MyIntf.Invoke(di,GUID_NULL,0,DISPATCH_METHOD,MyDispParams,nil, nil, nil); // (关键位置)
OleCheck(HR);
//更新内存变量的值
paramcls.ParamValue:=pr.ResultValue;
......
end;
============================
ocx中的方法的代码
procedure TafxBaseFunc.func_Add(Value: SYSUINT);
var
pPRParamRecord;
i:Integer;
fSUMouble;
begin //exit; <----
pPR:=Pointer(Value);
try
fSUM:=0;
for i:=0 to pPR.ParamCount-1 do
begin
case pPR.ParamTypeArray of
VT_UINT,VT_INT,VT_I2,VT_I4,VT_R4,VT_R8:fSUM:=fSUM+StrToFloat(pPR.ParamValueArray);
end;
end;
pPR.ResultValue:=FloatToStr(fSUM);
pPR.ResultType:=VT_R8;
except
pPR.ResultValue:='0';
pPR.ResultType:=VT_R8;
end;
end;
经过多个方面的测试,有以下现象和结论:
1。代码能运行,可以得到所需结果,但是平均30秒到1分钟左右,会出现错误,有些错误可以捕捉,有些则直接导致程序关闭;
2。如果把ocx中func_Add的代码屏蔽,即不做运算,则不会有错误出现;
结论:指针访问出现错误。
问题:哪个地方的写法导致了这个错误呢?怎么解决?注:程序中有可能出现临界区的地方都使用了互斥,而且经过检测排除了那种可能。