可能重复:
How to also prepare for 64-bits when migrating to Delphi 2010 and Unicode
因为我相信 64位 Delphi编译器很快就会出现, 如果有人知道什么样的节目,我很好奇 现在 32位将编译和工作而不做任何更改 使用 64位编译器时。
如果有一般规则,我们应该做出哪些改变 系统地在我们的旧程序中编译 为 64位?
当 64位编译器突然出现在这里时,做好准备是很好的...
任何建议都将不胜感激。
答案 0 :(得分:80)
首先,免责声明:虽然我为Embarcadero工作。我不能代表我的雇主。我要撰写的内容是基于我自己对假设的64位Delphi应该如何工作的看法,但可能存在或不存在竞争性意见以及导致替代设计决策的其他预见或不可预见的不兼容性和事件。
那说:
有两种整数类型,NativeInt和NativeUInt,其大小将是 根据平台,在32位和64位之间浮动。他们一直都是 好几个版本。没有其他整数类型会改变大小 取决于目标的位数。
确保依赖于将指针值转换为的任何位置 整数或反之亦然使用NativeInt或NativeUInt作为整数 类型。在Delphi的更高版本中,TComponent.Tag应该是NativeInt。
我建议不要将NativeInt或NativeUInt用于非基于指针的值。尝试在32位和64位之间保持代码在语义上相同。如果需要32位范围,请使用Integer;如果您需要64位,请使用Int64。这样你的代码应该在两个位上都运行相同。只有当你使用某种类型的指针值(如引用或THandle)进行转换时,才应使用NativeInt。
尽可能使用PByte
进行指针算术,优先于NativeInt
或NativeUInt
。它足以满足大多数目的,并且更加类型安全,因为它不能(容易)被误认为是普通的整数类型,反之亦然。
类似指针的东西应遵循与指针类似的规则:object 引用(很明显),还有HWND,THandle等等。
不要依赖字符串和动态数组的内部细节,例如 他们的标题数据。
我们关于64位API更改的一般政策应该是保持 尽可能在32位和64位之间使用相同的API,即使这意味着 64位API不一定利用机器。对于 例如,TList可能只处理MaxInt div SizeOf(指针) 元素,以保持计数,索引等为整数。因为 整数类型不会浮动(即根据位数改变大小),我们 不希望对客户代码产生连锁反应:任何索引 通过Integer类型变量或for循环索引进行往返 将被截断并可能导致细微的错误。
如果API扩展为64位,则很可能会完成 一个额外的函数/方法/属性来访问额外的数据,这个 API也将以32位支持。例如,Length()标准 例程可能会为参数返回Integer类型的值 类型字符串或动态数组;如果一个人想要处理非常大的 动态数组,也可能有一个LongLength()例程 32位的实现与Length()相同。长度()会抛出 如果应用于超过2 ^ 32的动态数组,则为64位异常 元件。
与此相关,可能会改进错误检查 缩小语言操作,特别是缩小64位值 到32位的位置。这会影响分配的可用性 如果Length(),则将Length的值返回到Integer类型的位置 返回Int64。另一方面,专门针对编译器魔术 像Length()这样的函数,可能会有一些神奇的优点, 例如根据上下文切换返回类型。但优势不可能 同样采用非神奇的API。
动态数组可能支持64位索引。注意Java 即使在64位平台上,数组也仅限于32位索引。
字符串可能仅限于32位索引。我们很难受 时间到了想要4GB +字符串的人的现实原因 这真的是字符串,而不仅仅是托管的数据blob 动态数组也可以同样起作用。
也许是一个内置的汇编程序,但有一些限制,比如无法自由地与Delphi代码混合使用;在x64上还需要遵循异常和堆栈框架布局的规则。
答案 1 :(得分:8)
首先,FreePascal已经提供了64位支持。但它不是Delphi。
其次,我期待Delphi 1升级到Delphi 2时存在的同样问题。最大的问题是与地址空间有关,这里的问题就是指针将从4个字节扩展到8个字节。在WIN16中,它们使用2个字节,并且需要通过使用段和指针偏移来克服64KB边界的技巧。 (可以为几个任务使用默认段。)
某些数据类型也可能会变得比现在更大。整数类型最有可能是8个字节。 (以前在Windows 2中仅为2个字节。)枚举可能也会变大。但是大多数其他数据类型可能会保持其当前大小,因此这里没有太多变化。
另一个问题是内存需求。由于指针长度为8个字节,因此使用大量指针的应用程序也会占用更多内存。具有10.000个指针的列表将从40.000字节增加到80.000字节。您可能希望使用比32位系统更多的内存。
速度也会有所改变。由于处理器现在可以同时处理8个字节,因此它可以更快地处理数据。但是,由于指针和一些数据类型变得更大,接收或发送到某些设备或内存将会慢一点。通常,您的应用程序通常会稍微快一些,但实际上某些部分可能会变慢!
最后,Windows API中的更改将要求您使用64位API函数。也许Delphi编译器会做一些聪明的事情来允许代码调用32位API函数,但这会降低性能,因为处理器现在在本机64位模式和模拟32位模式之间切换。
答案 2 :(得分:4)
根据您的代码,您可以尝试使用FreePascal编译它,它支持32位和64位编译。编译器会警告您代码中可能存在错误的位置。
答案 3 :(得分:4)
当宣布Delphi 2009只会创建Unicode应用程序时,会提出许多类似的问题。最后,事实证明大多数现有代码在没有更改的情况下运行良好。棘手的部分是假设SizeOf(Char) = 1
和第三方组件可能正在这样做的代码。
我希望将64位Delphi转变为类似的体验。除了使用指针操作技巧的代码并且假定为SizeOf(Pointer) = 4
或SizeOf(Pointer) = SizeOf(Integer)
之外,所有内容都不会出现问题。您现在可以通过调用SizeOf(Pointer)
而不是硬编码4
并在需要指针大小的整数时使用NativeInt
或NativeUInt
来解决此类问题。
如果您希望代码与Delphi 2007一起使用,则应使用SizeOf(Pointer)
而不是SizeOf(NativeInt)
。Delphi 2007有一个令人遗憾的错误导致SizeOf(NativeInt)
返回8而不是4应该。这在Delphi 2009中得到了修复。
答案 4 :(得分:3)
绝大多数简单的应用程序应该可以正常工作。据我所知,只有手动使用指针的应用程序才有风险。实际上,如果指针现在是64位,并且您在计算中使用它与整数或基数(默认情况下仍为32位),您将遇到麻烦。我还认为将指针作为参数的API函数的声明使用cardinal
而不是(无符号)本机整数类型是很常见的。
要使代码在任何平台上运行良好,在使用指针和整数时,应该使用NativeUInt
s(IIRC,现在没有Deplhi编译器)而不是cardinal
s
答案 5 :(得分:3)
只要Embarcadero没有发布有关其64位实现的官方信息就不容易辨别。您应该检查指向,指针,整数和红衣主教的任何演员,假设它们是本机平台大小,包括对象属性和引用(即将Integer存储在TObject属性中,这是一个指针,或者使用Tag来存储引用而不是数字)。
在递增(或递减)最大(最小)大小的值时,您还必须确保没有代码依赖于“环绕”效果。
检查依赖于数据大小的结构中的任何代码,并且不要正确使用SizeOf(),并且在数据集最重要时总是使用SizeOf()。如果大小可以更改,请检查将数据写入/读取到文件的代码,尤其是在需要在32位和64位代码之间交换数据时。
检查Win64更改,如果应用程序调用API并直接管理Windows消息。必须检查手动编码的ASM代码是否具有64位兼容性(编写64位汇编程序的规则要严格得多)。
答案 6 :(得分:2)
除了明显的指针< - > int tasks :(使用intptr / nativeint / ptrint等)
在将现有标头移植到win64时,我注意到了打包记录问题。
答案 7 :(得分:1)
我的2美分:
在过去,每个asm作家都被推到了使用BASM
外部asm64是可以接受的并使用旧的inlclude xy.obj代码, 虽然任何方式都需要完全重写
调试器& CPU64:问题是这还有吗?
D64 Float Extended:这仍然是80位漂浮吗?
HP
答案 8 :(得分:0)
作为一个完整的猜测,任何不依赖于特定字大小的代码,或者可以根据编译器所说的来调整其字大小的代码都没问题。