type
TMy=class
private
FValue:integer;
public
procedure MyTest;
constructor Create(i:integer);
destructor Destroy;override;
end;
PMy=^TMy; TForm1 = class(TForm)
......
public
procedure My(var msg:TMessage);message WM_My;
end;......{TMy}
constructor TMy.Create(i:integer);
begin
inherited Create;
FValue:=i;
Form1.Memo1.Lines.Add('TMy.Create');
end;destructor TMy.Destroy;//override;
begin
Form1.Memo1.Lines.Add('TMy.Destroy');
inherited;
end;procedure TMy.MyTest;
begin
Form1.Memo1.Lines.Add('TMy.MyTest - FValue : '+inttostr(FValue));
end;//************procedure TForm1.My(var msg:TMessage);
var pmy:PMy;
begin
if msg.WParam=1 then
begin
pmy:=PMy(msg.LParam);
pmy.MyTest;
end;
end;procedure TForm1.Button15Click(Sender: TObject);
var my:TMy;
begin
my:=TMy.Create(123);
my.MyTest;
PostMessage(handle,WM_My,1,integer(@my));
end;procedure TForm1.Button16Click(Sender: TObject);
var my:TMy;
begin
my.MyTest;
end;procedure TForm1.Button17Click(Sender: TObject);
var my:TMy;
begin
my:=TMy.Create(1);
my.MyTest;
my.Free;
end;按下 Button15 后,打印出信息 如下:
TMy.Create
TMy.MyTest - FValue : 123
TMy.MyTest - FValue : 123
按下 Button16 后,打印出信息 如下:TMy.MyTest - FValue : 14226404
按下 Button16 后,打印出信息 如下:
TMy.Create
TMy.MyTest - FValue : 1
TMy.Destroy
问题:
1、Button15 结束后,对象“my”有没有被释放掉?为什么不打印“TMy.Destroy”?为什么在 WM_My处理函数中,还能调用MyTest方法 且 打印 结果 正确??
2、为什么 Button16 按下后 ,没有创建对象就直接调用MyTest 却 没有报错,也打印出了信息??且既没有“TMy.Create”也没有“TMy.Destroy”被打印出来??如上 两点 中 5个问题,请解答,谢谢。
var p:PMy;//pmy 改为 p
begin
if msg.WParam=1 then
begin
p:=PMy(msg.LParam);
p.MyTest;
end;
end;
procedure TForm1.My(var msg:TMessage);
var p:PMy;//pmy 改为 p
begin
if msg.WParam=1 then
begin
p:=PMy(msg.LParam);
p.MyTest;
p.free; // 加了这句,但出错
end;
end;
p.free; // 加了这句,但出错
这样当然会出错,改成p^.free应该就没问题。建议先去学学指针之类的知识
var p:TMy;
begin
if msg.WParam=1 then
begin
p:=PMy(msg.LParam)^;
p.MyTest;
p.Free;
end;
end;
PostMessage(handle,WM_My,1,integer(@my))
改成
PostMessage(handle,WM_My,1,integer(my))然后把WM_My消息处理函数改成这样:
var p:TMy;
begin
if msg.WParam=1 then
begin
p:=TMy(msg.LParam);
p.MyTest;
p.Free;
end;
end;
多谢了,脑子一团乱。
那个Button16,为什么只要“有函数就成”?能讲解讲解不?
所以button16那样的方式,可以成功,
据我观察,在我的机器上,类似的变量可以定义两个,var my, my2:TMy;
begin
my.MyTest; //esi
my2.MyTest;//edi
end;
//因为esi, edi里一般都是有值的,不会被判定为nil,cpu根据里边的值(希望没指向一个无法访问的地址啊),相对的根据位移,找到Finteger对应地址,取出值来,这样是说的过去的
这样仍然行的通,但如果你再多定义一个,my3:Tmy,就不行了,寄存器不够用的了,这时就用到ebp-xx这样的堆栈值了,那时就AV了,因为堆栈上的事就不好说了
另外,EBX寄存器可能让self偷偷的占去了
像这种调用,一般是直接调用这个函数,把对象当做隐含参数传递给函数,你没有用到对象里的数据,当然不出错。
delphi在这种情况下的调用纯粹就是静态调用而已。
private
FValue:integer;
的吗?
并不是我想当然的说说而已
另外,大富翁论坛的这个帖子似乎分析的更详细
http://www.delphibbs.com/keylife/iblog_show.asp?xid=31260
如果这个成立,你试过多声明几个局部变量没有?在我的机器上,第三个未create的局部变量作MyTest操作时就会出av错误,前两个怎么也不会出错
procedure TForm1.Button19Click(Sender: TObject);
var i:integer;
my:TMy;
begin
if my=nil then
memo1.Lines.Add('nil')
else
memo1.Lines.Add('<> nil');
memo1.Lines.Add('integer(My) : '+inttostr(integer(My)));
My.MyTest;
copymemory(@i,pointer(integer(My)+sizeof(pointer)),sizeof(integer));
memo1.Lines.Add('i : '+inttostr(i));
end;
打印出来时这样:
<> nil
integer(My) : 4388748
TMy.MyTest - FValue : -217126717
i : -217126717
说明啥不?