Y
yanfei0891_firs
Unregistered / Unconfirmed
GUEST, unregistred user!
http://www.tommstudio.com/newclub30/d_displayjqxw.asp<br><br><br>怎样按名字调用某个类的方法?(在 不知道方法的参数个数及类型 的条件下)<br>这篇文章 http://www.tommstudio.com/newclub30/d_displayjqxw.asp 提供了<br>一种方法可以调用,但当方法的参数有real,或者currency型时 传入的参数值<br>就不对了,大家知道是为什么吗?<br>具体的程序如下:<br>调用的方法:<br>function ExecuteRoutine(AObj: TObject; AName: string;<br> Params: array of const): DWord;<br> const<br> RecSize = SizeOf(TVarRec); // 循环处理参数列表时递增的字节数<br> var<br> PFunc: Pointer;<br> ParCount: DWord;<br> begin<br> if not Assigned(AObj) then<br> raise Exception.Create ('你确定传进来的是一个对象?');<br> PFunc := AObj.MethodAddress(AName); // 获取方法地址<br> if not Assigned(PFunc) then<br> raise Exception.CreateFmt('找不到 %s 的 Method: %s', [AObj.ClassName,<br> AName]);<br> <br> ParCount := High(Params) + 1; // 获取参数个数<br><br> asm<br> PUSH ESI // 保存 ESI,我们待会儿要用到它<br><br> MOV ESI, Params // ESI 指向参数表首址<br> CMP ParCount, 1 // 判断参数个数<br> JB @NoParam<br> JE @OneParam<br> CMP ParCount, 2<br> JE @TwoParams<br><br> @ManyParams: // 超过两个参数<br> CLD // 清空方向标志<br> MOV ECX, ParCount<br> SUB ECX, 2 // 循环 ParCount - 2 次<br> MOV EDX, RecSize // EDX 依次指向每个参数的首址,每次递增 8 Bytes<br> ADD EDX, RecSize // 跳过前两个参数<br> @ParamLoop:<br> MOV EAX, [ESI][EDX] // 用基址变址寻址方式取得一个参数<br> PUSH EAX // 参数进栈<br> ADD EDX, RecSize // EDX 指向下一个参数首址<br> LOOP @ParamLoop<br><br> @TwoParams: // 两个参数<br> MOV ECX, [ESI] + RecSize<br><br> @OneParam: // 一个参数<br> MOV EDX, [ESI]<br><br> @NoParam:<br> MOV EAX, AObj // 传入实例地址(即,隐藏参数 Self)<br> CALL PFunc // 调用方法<br> MOV Result, EAX // 返回值放入 Result<br><br> POP ESI // 记得还原<br> end;<br> end;<br>被调用的方法<br>procedure TForm1.avg(Const a,b : Currency;var c : Currency);<br>begin<br> c := (a + b)/2 ;<br>end;<br>调用:<br> begin<br> var j : Currency;<br> ExecuteRoutine(Form1,'avg',[12.21,12.32,@j]);<br> end;<br>调用时跟踪 a,b的值都不对了,但如果 a,b设成integer型就可以了