有多个参数传入,需要传出多个结果,所以考虑到使用传一个指针的方法来实现,当然是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
pr:ParamRecord; //前面有定义
//------
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
pPR:PParamRecord;
i:Integer;
fSUM:Double;
begin //exit; <----
pPR:=Pointer(Value);
try
fSUM:=0;
for i:=0 to pPR.ParamCount-1 do
begin
case pPR.ParamTypeArray[i] of
VT_UINT,VT_INT,VT_I2,VT_I4,VT_R4,VT_R8:fSUM:=fSUM+StrToFloat(pPR.ParamValueArray[i]);
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的代码屏蔽,即不做运算,则不会有错误出现;
结论:指针访问出现错误。
问题:哪个地方的写法导致了这个错误呢?怎么解决?注:程序中有可能出现临界区的地方都使用了互斥,而且经过检测排除了那种可能。
8 个解决方案
#1
D可以直接创建自动化对象,没必要这么麻烦啊
#2
我现在创建的就是自动化对象啊。我需要在程序中根据方法的名字GetIDsOfNames后去invoke他,请不要跑题。
#3
帮顶
#4
谢谢。
#5
帖子提前太频繁了!真龌龊的提示,我啥时候提前太频繁了?才点了一次而已,真不知道开发程序的程序员怎么设计的。
#6
没人回答。看来,人总要靠自己的。
#7
D作OCX也很简单,没有必要自己去实现Invoke啊
#8
终于有人回复了。感激ing...
不过,问题是这样,假如你有一个系统,可以在系统中集成符合某个标准的ocx插件,并且调用ocx中的函数,那么在系统编译的时候,并不知道ocx提供了什么函数以及函数名是什么,请问,你会怎么实现?
我的方法是通过访问ocx插件的类型库,得到可用函数的列表,然后通过GetIDsOfNames后去Invoke它。
有什么替代的方法么?
不过,问题是这样,假如你有一个系统,可以在系统中集成符合某个标准的ocx插件,并且调用ocx中的函数,那么在系统编译的时候,并不知道ocx提供了什么函数以及函数名是什么,请问,你会怎么实现?
我的方法是通过访问ocx插件的类型库,得到可用函数的列表,然后通过GetIDsOfNames后去Invoke它。
有什么替代的方法么?
#1
D可以直接创建自动化对象,没必要这么麻烦啊
#2
我现在创建的就是自动化对象啊。我需要在程序中根据方法的名字GetIDsOfNames后去invoke他,请不要跑题。
#3
帮顶
#4
谢谢。
#5
帖子提前太频繁了!真龌龊的提示,我啥时候提前太频繁了?才点了一次而已,真不知道开发程序的程序员怎么设计的。
#6
没人回答。看来,人总要靠自己的。
#7
D作OCX也很简单,没有必要自己去实现Invoke啊
#8
终于有人回复了。感激ing...
不过,问题是这样,假如你有一个系统,可以在系统中集成符合某个标准的ocx插件,并且调用ocx中的函数,那么在系统编译的时候,并不知道ocx提供了什么函数以及函数名是什么,请问,你会怎么实现?
我的方法是通过访问ocx插件的类型库,得到可用函数的列表,然后通过GetIDsOfNames后去Invoke它。
有什么替代的方法么?
不过,问题是这样,假如你有一个系统,可以在系统中集成符合某个标准的ocx插件,并且调用ocx中的函数,那么在系统编译的时候,并不知道ocx提供了什么函数以及函数名是什么,请问,你会怎么实现?
我的方法是通过访问ocx插件的类型库,得到可用函数的列表,然后通过GetIDsOfNames后去Invoke它。
有什么替代的方法么?