迁移到Delphi 2010和Unicode时如何准备64位

use*_*142 13 migration delphi 64-bit

由于下一版本不支持64位支持,因此不再需要等待将现有代码库一次性迁移到unicode和64位的可能性.但是,如果我们在进行unicode转换时已经准备好了64位代码,那就太好了.这样可以最大限度地减少最终出现在2020版本中的影响.任何建议如何处理这个问题,如果它没有在2020年之前到达那么会引起太多的混乱?

Bar*_*lly 20

还有一个类似的问题,但我也会在这里重复我的回复,以确保尽可能多的人看到这个信息:

首先,免责声明:虽然我为Embarcadero工作.我不能代表我的雇主.我要撰写的内容是基于我自己对假设的64位Delphi应该如何工作的看法,但可能存在或不存在竞争性意见以及导致替代设计决策的其他预见或不可预见的不兼容性和事件.

那说:

  • 有两种整数类型,NativeInt和NativeUInt,其大小将在32位和64位之间浮动,具体取决于平台.他们已经出现了不少版本.没有其他整数类型会根据目标的位数改变大小.

  • 确保依赖于将指针值转换为整数的任何位置(反之亦然)使用NativeInt或NativeUInt作为整数类型.TComponent.Tag在Delphi的更高版本中应该是NativeInt.

  • 我建议不要将NativeInt或NativeUInt用于非基于指针的值.尝试在32位和64位之间保持代码在语义上相同.如果需要32位范围,请使用Integer; 如果您需要64位,请使用Int64.这样你的代码应该在两个位上都运行相同.只有当你使用某种类型的Pointer值(例如引用或THandle)进行转换时,才应使用NativeInt.

  • 类似指针的东西应该遵循与指针类似的规则:对象引用(显然),还有像HWND,THandle等的东西.

  • 不要依赖字符串和动态数组的内部细节,比如它们的标题数据.

  • 我们关于64位API更改的一般策略应该是尽可能在32位和64位之间保持相同的API,即使这意味着64位API不一定利用机器.例如,TL​​ist可能只处理MaxInt div SizeOf(指针)元素,以便将Count,索引等保持为Integer.因为Integer类型不会浮动(即根据位数改变大小),我们不希望对客户代码产生连锁反应:任何通过Integer类型变量或for循环索引往返的索引都会被截断并可能导致细微的错误.

  • 在API扩展为64位的情况下,它们很可能使用额外的函数/方法/属性来访问额外的数据,并且此API也将以32位支持.例如,对于类型为string或dynamic array的参数,Length()标准例程可能会返回Integer类型的值; 如果想要处理非常大的动态数组,可能还有一个LongLength()例程,其32位实现与Length()相同.如果应用于具有超过232个元素的动态数组,则Length()将在64位中引发异常.

  • 与此相关,可能会改进错误检查以缩小语言中的操作范围,特别是将64位值缩小到32位位置.如果长度()返回Int64,这将会影响将Length的返回值赋给Integer类型的位置的可用性.另一方面,特别是对于像Length()这样的编译器魔术函数,可能会有一些优势,例如根据上下文切换返回类型.但是在非魔术API中不能同样采用优势.

  • 动态数组可能支持64位索引.请注意,Java阵列仅限于32位索引,即使在64位平台上也是如此.

  • 字符串可能仅限于32位索引.对于想要4GB +字符串的人来说,我们很难找到真正的字符串,而不仅仅是托管数据块,动态数组也可以用它们.

  • 也许是一个内置的汇编程序,但有限制,就像不能自由地混合使用Delphi代码; 在x64上还需要遵循异常和堆栈框架布局的规则.


And*_*eck 7

首先,查看与非delphi库和api调用交互的位置,它们可能不同.在Win32上,具有stdcall调用会话的库被命名为_SomeFunction @ 4(@ 4表示参数的大小等).在Win64上,只有一个调用约定,并且dll中的函数不再被装饰.如果从dll文件导入函数,则可能需要调整它们.

请记住,在64位exe中,您无法加载32位dll,因此,如果您依赖第三方dll文件,则还应检查这些文件的64位版本.

另外,看看Integers,如果依赖于它们的最大值,例如当你让它们溢出并等待发生的那一刻时,如果改变整数的大小,它将导致麻烦.

此外,当使用流,并且您想要序列化不同的数据时,如果包含整数,则会导致麻烦,因为整数的大小发生了变化,并且您的流将不同步.

因此,在您依赖于整数或指针大小的位置,您需要进行调整.在序列化sush数据时,您还需要记住此大小问题,因为它可能导致32位和64位版本之间的数据不兼容.

此外,使用Lazarus IDE的FreePascal编译器已经支持64位.这个替代的Object Pascal编译器与Pascal的Borland/Codegear/Embarcadero方言不是100%兼容,所以只需用64位重新编译就可能不那么简单,但它可能有助于指出64位的问题.


ska*_*adt 6

转换到64位应该不会非常痛苦.从故意了解重要的整数大小开始.不要使用"整数"而是使用Int32表示大小为32位的整数,使用Int64表示大小为64位的整数.在最后一位转换中,Integer的定义从Int16转到Int32,因此通过指定精确的位深度来保证它的安全性.

如果您有任何内联汇编,请创建一个pascal等效项并创建一些单元测试以确保它们以相同的方式运行.对两者进行一些时序测试,看看组件是否仍然运行得足够快.如果是,那么您将需要根据需要对两者进行更改.

  • 依赖于整数大小的一个特殊情况是依赖于整数和指针是*相同*大小,无论大小如何.另外,假设整数和*句柄*的大小相同.Delphi现在将句柄视为整数,但API将它们定义为指针. (3认同)