Delphi 使用ASM调用对象方法
为了更好地解释我想要实现的目标,我将从一些有效的东西开始 假设我们有一个过程可以调用另一个过程并向其传递字符串参数:Delphi 使用ASM调用对象方法,delphi,assembly,delphi-2010,basm,Delphi,Assembly,Delphi 2010,Basm,为了更好地解释我想要实现的目标,我将从一些有效的东西开始 假设我们有一个过程可以调用另一个过程并向其传递字符串参数: procedure CallSaySomething(AProc: Pointer; const AValue: string); var LAddr: Integer; begin LAddr := Integer(PChar(AValue)); asm MOV EAX, LAddr CALL AProc; end; end; 这是我们将调用的
procedure CallSaySomething(AProc: Pointer; const AValue: string);
var
LAddr: Integer;
begin
LAddr := Integer(PChar(AValue));
asm
MOV EAX, LAddr
CALL AProc;
end;
end;
这是我们将调用的过程:
procedure SaySomething(const AValue: string);
begin
ShowMessage( AValue );
end;
现在我可以打电话给说类似的话了(经过测试,效果良好(:):
我的问题是,我如何实现类似的功能,但这次说点什么应该是一种方法:
type
TMyObj = class
public
procedure SaySomething(const AValue: string); // calls show message by passing AValue
end;
所以,如果你还和我在一起,我的目标是得到一个类似于:
procedure CallMyObj(AObjInstance, AObjMethod: Pointer; const AValue: string);
begin
asm
// here is where I need help...
end;
end;
我已经试过很多次了,但我的装配知识有限。使用asm的原因是什么 调用objects方法时,实例指针必须是方法调用中的第一个参数
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses System.SysUtils;
type
TTest = class
procedure test(x : integer);
end;
procedure TTest.test(x: integer);
begin
writeln(x);
end;
procedure CallObjMethod(data, code : pointer; value : integer);
begin
asm
mov eax, data;
mov edx, value;
call code;
end;
end;
var t : TTest;
begin
t := TTest.Create();
try
CallObjMethod(t, @TTest.test, 2);
except
end;
readln;
end.
您可能可以通过阅读本文找到解决方法。但何必麻烦呢,声明一个对象的
类型TMyMethod=procedure(Const aValue:string)
并替换CallMyObj
中的指针类型,并删除AObjectInstance
。然后您的调用将像aobjectmethod(aValue)一样简单:
@LURD这是一种非常简单的方式来描述我试图实现的目标,最后,我将使用未知数量的参数和类型的参数调用方法,我找到了一种解决方法…使用“TExec=procedure of Object;”hack和“PUSH DWORD PTR AValue;”,谢谢你的链接谢谢你的代码,到目前为止我已经找到了一种方法,你的方法也很好,使用ASM的原因是因为我发布的“示例”代码是最低限度的,最后,我将传递未知数量的参数和参数类型方法使用TValue的数组传递未知类型的未知数量的参数。是的,但我想避免使用RTTI,我想使用RTTI获取信息(在启动时),然后使用ASM调用方法。另外,如果您已经发布了方法测试,那么您可以使用LCode:=t.MethodAddress('Test'));并通过LCode而不是@TTest.test
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses System.SysUtils;
type
TTest = class
procedure test(x : integer);
end;
procedure TTest.test(x: integer);
begin
writeln(x);
end;
procedure CallObjMethod(data, code : pointer; value : integer);
begin
asm
mov eax, data;
mov edx, value;
call code;
end;
end;
var t : TTest;
begin
t := TTest.Create();
try
CallObjMethod(t, @TTest.test, 2);
except
end;
readln;
end.