如果你在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中稍微捅了一下,但是我没有看到任何提到这个“身份指针”的东西或它的用途.有谁知道为什么会这样?对于从至少D3到D2010的每个版本的Delphi,这似乎都是正确的.
解决方法
它非常简单:包和动态链接.
BPL是DLL. DLL通过修补的表进行链接,而不是EXE或DLL中的所有代码链接到正在修补的DLL(这会对在多个进程之间共享只读内存造成很大的危害).为了防止在代码中的某处或者EXE或DLL的typeinfo中引用TypeInfo(SomeType),在链接到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
希望这可以解决它.
原文地址:https://www.jb51.cc/delphi/102360.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。