代码如下
unit Unit4;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DBCtrls, Mask;
type
TForm4 = class(TForm)
Button2: TButton;
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure add(a:integer);
class procedure add1(a:integer);
end;
procedure add2(a:integer);
var
Form4: TForm4;
c:integer;
implementation
{$R *.dfm}
procedure add2(a:integer);
begin
c:=a+1;
end;
procedure TForm4.add(a: integer);
begin
c:=a+1;
end;
class procedure TForm4.add1(a: integer);
begin
c:=a+1;
end;
end.
汇编代码
004FB1E8 BA01000000 mov edx,$00000001
004FB1ED E836FFFFFF call TForm4.add //成员函数
004FB1F2 BA01000000 mov edx,$00000001
004FB1F7 A15CAA4F00 mov eax,[$004faa5c]
004FB1FC E82FFFFFFF call TForm4.add1 //类函数
004FB201 B801000000 mov eax,$00000001
004FB206 E815FFFFFF call add2 //单元函数
1.成员函数数
别看它的呼叫那么简单,其实也要给eax传值的. 成员函数的调用需要对eax隐含的传值.传什么呢?答案就是:类的实体地址. 如以上
TForm4类的实体是Form4 那么 eax=Pointer(Form4) 这样才能call.因为是成员函数,所以eax都是指向 Pointer(self)的.这也是为什么成员函数不能作为windows的回调,线程函数的原因.
procedure TForm4.Button1Click(Sender: TObject);
var p:PPropInfo;
setproc:Pointer;
tp:Pointer;
begin
p:=GetPropInfo(self.DBText1,'Color',[TTypeKind.tkInteger]);
ListBox1.Items.Add(p^.Name);
setproc:=p^.SetProc;
tp:=DBText1;
asm
push eax
mov eax,tp //实体地址传值给eax
mov edx,$80 //传参数
call setproc
pop eax
end;
end;
以上代码是修改一个
DBText的Color属性.如果没有传eax是会失败的.
2.类函数
与成员含数类似,不过EAX就是传类
TForm4的地址3.单元函数
正常的函调用无须隐含传什么值