如何在不同单元访问类的私有方法(静态方法)并获得其地址(100分)

D

dwf3110

Unregistered / Unconfirmed
GUEST, unregistred user!
如何在不同单元访问类的私有方法(静态方法)并获得其地址?知道的能否说明一下原理,并举个实例。
 
用汇编应该行吧
 
可以直接在另一个单元中定义一个继承这个类的新类.什么也不用扩展.
这样可以把这个类与这个单元成为友元,那么这个单元中就可以直接访问这个类的私有成员了.

例如:TStringGrid有个DeleteRow(..);的私有方法.
我在Unit1单元中想访问TStringGrid的这个DeleteRow(..);的私有方法.
我可以在Unit1中定义一个TStringGrid继承类TMyStringGrid=Class(TStringGrid);
OK
下面我在Unit1中的实现部份就可以用TMyStringGrid(StringGrid1).DeleteRow(..)操作了
 
to Yepemig:
你说的方法只是对其的保护区域的访问,而不是私有区域的访问。
to dreamfly1024:
用汇编,如何用汇编。
 
跟你提示一下吧:
你想修改类的私有变量或调用私有方法,那么就得想办法得到那些变量和方法在类中的一个入口地址,然后跟据变量所占字节大小,推算其它私有方法的地址。
那么你怎么得到一个入口的私有变量地址呢?
我们查一下那个类,不难发现有:
property Width: Integer read FWidth write SetWidth;
我们能访问Width,而Width直接是调用私有变量FWidth,由此我们可以得到FWidth的地址。
请看一个例子:
procedure TForm1.btn1Click(Sender: TObject);
var
pWidth:pInteger;
begin
ShowMessage(IntToStr(edt1.Width));
pWidth:=@edt1.Width;
pWidth^:=200;
ShowMessage(IntToStr(edt1.Width));
end;
我们修改了私有变量FWidth的值不是调用SetWidth,而是直接操纵地址。

直接操纵地址是比较危险的,要特别小心。
 
to danng:
对于你上面的方法,有一点疑问,pWidth:=@edt1.Width
其中width为TControl的一个属性,那么@edt1.Width的到的是什么呢?
另外,你的操作具有一定危险性,若:
property Width: Integer read SetWidth write SetWidth 那么我们这种方法就会出错。

下面是我做的一个Demo:
var
P1, P2, P3: Pointer;
vW: Integer;
begin
p1 := Pointer(TEdit);
P2 := @Edit1.Width;
//$7968为类TControl的方法setwidth与 类TEdit 之间的内存相对位置
p2 := Pointer(Integer(P1) + $7968);
vW := 15;
P3 := Edit1;
asm
push eax
push edx
mov edx, vW
mov eax, p3
call p2
pop edx
pop eax
end;
end;
对于$7968需要特殊处理,处理方式需要一步步跟踪Cpu地址得到。
经验证成功更改了Edit1的宽度,并且是通过SetWidth设置的,和自己的要求相符。
 
@edt1.Width是那个类对应的FWidth,你要操纵那个类的私有变量及方法,当然是需要完全了解它的内部地址结构,不然肯定会出错的。
像你说的"并且是通过SetWidth设置的",如果是这样的话,那我何须访问它的私有方法,我直接调用它的Width:=100;不就行了吗?
 
顶部