PASCAL指针和过程的问题(50分)

  • 主题发起人 主题发起人 HORNEY
  • 开始时间 开始时间
H

HORNEY

Unregistered / Unconfirmed
GUEST, unregistred user!
各位请看;
TYPE TA=CLASS(TBUTTON)
PROCEDURE INVOKE(MNAME: STRING);
PROCEDURE GO;
PROTECTED
STATUS;INTEGER
END;

PROCEDURE TA.INVOKE(MNAME: STRING);
VAR PRO
PROCEDURE;
BEGIN
@PRO;=SELF.METHODADDRESS(MNAME);
PRO;
END;

PROCEDURE TA.GO;
BEGIN
STATUS:=3;//这里会有ACCESS VIOLATION错误
END;
这是一个DELHI过程类型的问题,通过MNAME能够将TA.GO的指针给PRO
PRO也能顺利调用TA.GO,但是只要它对类成员的操作都会错误,OTHERS都正
常,敢问各位是怎么回事.
(COMMENT:之所以类一开始要继承一个TBUTTON,是因为METHODADDRESS
只对VCL成员有用)
 
@PRO;=SELF.METHODADDRESS(MNAME);

写错了吧
@PRO;=SELF.METHODADDRESS(GO);
 
没错,METHODADDRESS是用字符串来定位过程的.
 
加上一点前提条件
1.类已被正确创建.
2.全部代码均被正确编译,即没有被OPTIMIZE的代码.
 
Wha,your font is so large,it's very difficult Browsing!
 
大家倒是想个办法呀,分我会另加的,求求各位了
555。。。
另:我分配内存也试过了,也不行。
 
应“话机变量”兄要求,将代码重贴一启遍。
Type TA = Class(TButton)
procedure Invoke(Mname: string);
procedure Go;
Protected
Status: Integer

End;

procedure TA.Invoke(Mname: string);
Var Pro: Procedure;
begin
@Pro;=Self.MethodAddress(Mname);
pro;
end;

Procedure TA.Go;
begin
Status:=3;//这里会有ACCESS VIOLATION错误
End;
这是一个DELHI过程类型的问题,通过MNAME能够将TA.GO的指针给PRO
PRO也能顺利调用TA.GO,但是只要它对类成员的操作都会错误,OTHERS都正
常,敢问各位是怎么回事.
(COMMENT:之所以类一开始要继承一个TBUTTON,是因为
METHODADDRESS只对VCL成员有用)
 
您的 Invoke 可以这样写:

procedure TA.Invoke(Mname: string);
type Call = procedure of object;
Var Method: TMethod;
begin
Method.Data := self;
Method.Code := self.MethodAddress(Mname);
Call(Method);
end;
 
错误的原因很简单,PROCEDURE OF OBJECT和PROCEDURE的调用是不同的
进栈的个数不同,PROCEDURE OF OBJECT相当于要进栈其SELF
这样,我们才能在类方法里使用类成员,如果没有SELF,DELPHI是无法用到其类成员的

我们把类看成是一个记录,而类成员方法是记录内的一个函数指针
我们调用这个函数的时候,类成员方法根据堆栈来找出自己的记录地址,也就是SELF
这样我们才可以根据相对偏移访问到其类成员

具体的实现我们可以从MAKEOBJECTINSTANCE这个函数里看出些端倪

因为你调用INVOKE的PRO的时候,当成的是过程而非PROCEDURE OF OBJECT,所以
调用PRO的时候是不会将SELF进栈的(有的语言有时候用EAX表示SELF地址),因此导致
访问STATUS出现内存访问冲突错误.
如果我们申明使用的PRO为PROCEDURE OF OBJECT,就肯定没问题了

注意:存贮PROCEDURE OF OBJECT的变量是8字节,PROC则是4字节.
而METHODADDRESS返回的只有4字节的地址
所以我们需要将8字节的高位设置为SELF

PINTEGER(@@PRO+4)^:=@SELF;
@PRO:=SELF.METHODADDRESS(MNAME);

你该给我加600分了,好累
 

Similar threads

C
回复
9
查看
220
chuQingSheng
C
B
回复
18
查看
326
blad_pitt
B
W
回复
15
查看
145
wjh_wy
W
A
回复
4
查看
151
awfigsk
A
N
回复
4
查看
170
netxray
N
后退
顶部