使用Dephi使用指针的频率不会像C那么高,但是确实也会使用,特别是操作VMT的时候,下面是根据VMT的一些知识写的一个程序片段,在写出来之后,结合自己的理解,进行了比较详细的注释,在注释的过程中,对于所写的内容有了更加清晰的认识。
procedure TForm1.btn1Click(Sender: TObject);
var
iInstanceSize: Integer;
s: string;
aP: Pointer;
tmp: Pointer;
tmp2: Pointer;
begin
//获取对象指针
ap := Self;
//ap^代表取出ap中存储地址处的内容,此处仍然是一个指针,故写作Pointer(ap^)
//此时的ap中存储的已经是vmt的首地址
ap := Pointer(ap^);
//尝试取下InstanceSzie
//移动后到达一个地址,这里面存储的是InstancSize所在的地址,先转化为一个无类型指针
//由于已知,这个指针中存储的地址处存放的是一个Integer类型,因此可以进行如下操作
tmp2 := Pointer(Integer(ap) + vmtInstanceSize);
//由于已知,这个指针中存储的地址处存放的是一个Integer类型,因此可以进行如下操作
ShowMessage(Format('%d', [Integer(tmp2^)]));
//下面这句是上面步骤的简化版
ShowMessage(Format('%d', [Integer(Pointer(Integer(ap) + vmtInstanceSize)^)]));
//下面是这句是上面的精简版
iInstanceSize := (PInteger(Integer(ap) + vmtInstanceSize)^);
ShowMessage(Format('%d;Real Instance size:%d; Class Name:%s', [iInstanceSize, Self.InstanceSize, Self.ClassName]));
//类似上面的方式,可以取得一个字符串类型ClassName
tmp := Pointer(Integer(ap) + vmtClassName);
//tmp在上一句已经转化为一个指向ClassName的指针。
//由于字符串是用一个指针指向的,不是立即存储的,因此,下面先将 tmp存放的是指向字符串指针的首地址,因此,
//根据该首地址取出字符串的首地址
tmp := Pointer(tmp^);
//下面是将内存的首地址转化为一个固定类型的指针,随之取出内容
ShowMessage(PShortString(tmp)^);
end;
虽然说很简单,但是在这里先记下来,防止以后遗忘!