2013-01-09 25 views
15

我正在调整一个大的Delphi代码库到64位。在很多情况下,有些情况下指针被强制转换为/从32位值,类似于此行:德尔福64位:发现不正确的演员?

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

我在哪里可以找到这些类型转换我与他们取代NativeInt-蒙上而不是让他们在64正确位模式。

但是我不确定我是否找到了他们。由于“整数”(如果指针值高于整数范围,“64位转换将失败”),因为只有文本搜索字符串“integer(”是不够的

由于“类型我有一个想法:如果我可以强制内存管理器分配高于4GB的内存(所以指针值使用多于32位),那我会得到运行时错误,并且可以更容易地找到错误的类型。这是可能的吗?或者任何人都可以推荐一些其他的技术吗?

回答

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\AllocationPreference设置为REG_DWORD,值为0x100000并重新启动。

请注意,这可能会导致您的机器出现稳定性问题。许多应用程序无法应对此。特别是有很少的防病毒产品可以应付这种设置。 MSE是我发现的机器范围内自顶向下分配的工作。更重要的是,64位调试器不能在自顶向下分配下运行!所以你必须在没有调试器的情况下进行这种测试。我的QC report仍然是开放的,即使在XE3中也没有解决这个问题。

+2

谢谢,MEM_TOP_DOWN标志非常有趣。我正在工作的项目有一个自定义调试分配器,所以刚才我修改了使用标志。这是非常缓慢的,但我已经找到转换错误。 –