15

我正在努力使大型 Delphi 代码库适应 64 位。在许多情况下,有一些行将指针转换为/从 32 位值转换,类似于:

var
  p1,p2 : pointer;
begin
  inc(Integer(p1),10);
  p2 := Pointer(Integer(p1) + 42);

在哪里可以找到这些演员表,我已将它们替换为 NativeInt-casts,以使它们在 64 位模式下正确。

但是我不确定我是否找到了所有这些。有时演员阵容更加微妙,因此仅对字符串“integer(”进行文本搜索也是不够的。

由于如果指针值高于整数类型的范围,“整数(”转换将在 64 位中失败,我有一个想法:如果我可以强制内存管理器分配高于 4gb 的内存(因此指针值使用更多比32位)?然后我会得到运行时错误,并且可以更容易地找到错误的演员表。这可能吗?或者任何人都可以推荐一些其他技术吗?

4

1 回答 1

21

除了您正在使用的文本搜索之外,没有什么神奇的技巧可以找到这些演员表。如果编译器警告这样的演员表,那就太好了。我觉得很失望,它没有。

当您确实发现此类问题时,请不要更改为NativeInt. 将指针更改为类型化指针,并使用指针算法。

var
  p1, p2: PByte;
....
inc(p1, 10);
p2 := p2;
inc(p2, 42);

那么您的代码将永远安全。

在某些情况下,您需要强制转换为整数。例如,当将地址传递给SendMessage. 但将这些转换为任意一个WPARAMLPARAM视情况而定。

您强制运行时错误的想法是合理的,谢天谢地,不是原创的!您应该使用完整版的 FastMM 并定义AlwaysAllocateTopDown. 这会强制 FastMM 进行的调用VirtualAlloc传递MEM_TOP_DOWN标志。这会将您的大部分错误转换清除为运行时指针截断错误。

但是,这只会强制对内存管理器分配的内存进行自上而下的分配。您流程中的其他模块将使用自下而上的默认策略。您可以设置机器范围的设置来更改该默认策略。设置HKLM\System\CurrentControlSet\Control\Session Manager\Memory Management\AllocationPreferenceREG_DWORD0x100000并重新启动。

请注意,这可能会导致您的机器出现稳定性问题。许多应用程序无法应对这种情况。特别是很少有防病毒产品可以应对这种设置。MSE 是我发现适用于机器范围自上而下分配的一种。更何况 64 位调试器不能在自顶向下分配下运行!所以你必须在没有调试器的情况下进行这种测试。我的QC 报告仍处于打开状态,即使在 XE3 中也没有解决此问题。

于 2013-01-09T09:07:37.340 回答