gpt4 book ai didi

delphi - TTypeInfo 之前的 "identity pointer"是做什么用的?

转载 作者:行者123 更新时间:2023-12-03 14:47:04 29 4
gpt4 key购买 nike

如果您在 Delphi 内部进行了足够多的研究,您会发现一些奇怪的东西,并且显然没有关于编译器生成的 TTypeInfo 记录的记录。如果 PTypeInfo 指向地址 X 处的 TTypeInfo 记录,则在 X - 4 处您会发现接下来的 4 个字节描述了指向 X 的指针。例如:

procedure test(info: PTypeInfo);
var
addr: cardinal;
ptr: PPointer;
begin
addr := cardinal(info);
writeln('addr: ', addr);
dec(addr, 4);
ptr := PPointer(addr);
addr := cardinal(ptr^);
writeln('addr: ', addr);
end;

将编译器生成的任何合法 PTypeInfo 传递到此例程中,它将输出相同的地址两次。我在 TypInfo.pas 中浏览了一下,但没有看到任何提到这个“身份指针”或它的用途的内容。有谁知道为什么会这样?这似乎在 Delphi 的每个版本(至少从 D3 到 D2010)中都是如此。

最佳答案

非常简单:包和动态链接。

BPL 是 DLL。 DLL 是通过被修补的表来链接的,而不是 EXE 或 DLL 中的所有代码都链接到被修补的 DLL(这会对多个进程之间共享只读内存造成很大的损害)。为了防止在代码中某处引用 TypeInfo(SomeType) 或 EXE 或 DLL 的类型信息在链接 BPL 时被修改,而是通过导入表进行间接访问。

在此程序中,很容易看出静态链接与 BPL 链接的区别:

{$apptype console}
uses TypInfo, SysUtils;
type
TFoo = class(TObject);
var
x: PPTypeInfo;
begin
x := GetTypeData(TypeInfo(TFoo))^.ParentInfo;
Writeln(x^^.Name);
Writeln(Format('x %p', [x]));
Writeln(Format('x^ %p', [x^]));
end.

在我的本地计算机上,使用 dcc32 test.pas 编译,它输出:

TObject
x 00401B64
x^ 00401B68

但是当使用带有dcc32 -LUrtl test.pas的RTL包编译时,它输出:

TObject
x 004051F0
x^ 40001DA4

希望这能解决问题。

关于delphi - TTypeInfo 之前的 "identity pointer"是做什么用的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3443097/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com