在不知道参数个数的情况下,调用对象的方法.
function ExecuteRoutine(AObj: TObject
AName: string
Params: array of const): DWord
const
RecSize = SizeOf(TVarRec)
// 循环处理参数列表时递增的字节数
var
PFunc: Pointer
ParCount: DWord
begin
if not Assigned(AObj) then
raise Exception.Create ('你确定传进来的是一个对象?')
PFunc := AObj.MethodAddress(AName)
// 获取方法地址
if not Assigned(PFunc) then
raise Exception.CreateFmt('找不到 %s 的 Method: %s', [AObj.ClassName,
AName])
ParCount := High(Params) + 1
// 获取参数个数
asm
PUSH ESI // 保存 ESI,我们待会儿要用到它
MOV ESI, Params // ESI 指向参数表首址
CMP ParCount, 1 // 判断参数个数
JB @NoParam
JE @OneParam
CMP ParCount, 2
JE @TwoParams
@ManyParams: // 超过两个参数
CLD // 清空方向标志
MOV ECX, ParCount
SUB ECX, 2 // 循环 ParCount - 2 次
MOV EDX, RecSize // EDX 依次指向每个参数的首址,每次递增 8 Bytes
ADD EDX, RecSize // 跳过前两个参数
@ParamLoop:
MOV EAX, [ESI][EDX] // 用基址变址寻址方式取得一个参数
PUSH EAX // 参数进栈
ADD EDX, RecSize // EDX 指向下一个参数首址
LOOP @ParamLoop
@TwoParams: // 两个参数
MOV ECX, [ESI] + RecSize
@OneParam: // 一个参数
MOV EDX, [ESI]
@NoParam:
MOV EAX, AObj // 传入实例地址(即,隐藏参数 Self)
CALL PFunc // 调用方法
MOV Result, EAX // 返回值放入 Result
POP ESI // 记得还原
end
end
被调用的方法
procedure TForm1.avg(a,b : Currency;var c : Currency)
begin
c := (a + b)/2
end
调用:
begin
var j : Currency
ExecuteRoutine(Form1,'avg',[12.21,12.32,@j])
end
------
这个可能对你有帮助。