如果你有一个32位的Delphi程序要升级成64位,可以参考下面的攻略进行升级。
- 先升级成Unicode版本
- 在IDE环境下打开你的32位工程,添加并激活64位的平台,并且编译你的工程为64位的。
- 查找并处理如下的事项(指针的操作,NativeInt的大小,汇编的代码)
指针的操作
在你的代码里查找以下指针相关的操作:
指针的大小改变了
在32位的程序中, 指针是4bit,但是在64位程序中,指针是8bit.
你可以假定
SizeOf(Pointer)=SizeOf(Integer/Caridinal/LongInt)
- 如果你想增加指针的话,要意识到,64位的指针操作跟32位的指针操作是不一样的,所以你需要调整你的代码
正确的如下:
Myptr := PByte(P) + 10
兼容的写法:
MyPtr := PAnsiChar(P) + 10
错误的写法:
MyPtr := Pointer(Integer(P) + 10)
- 你不能假定
SizeOf(Pointer) := 4
正确的写法应该是:
Move(FSelection[Index + 1], FSelection[Index], (FSelectCount - index - 1) * SizeOf(Pointer);
错误的写法是:
Move(FSelection[Index + 1], FSelection[Index], (FSelectCount - Index - 1) * 4)
关于更多关于64位程序上的指针操作,请参考MSDN上的文章
整型类型
在64位的平台中,Integer依旧是4bit,但是NavtiveInt的大小改了。
- 在64位中,NativeInt大小是8Bit
- 在32位中,NativeInt大小还是4Bit
内联汇编
如果你的代码含有内联汇编代码,你需要检查汇编的代码,并做如下的修改:
- 64位的代码是不支持汇编跟pascal代码混合的,你需要把汇编代码换成pascal代码或者把汇编的代码提出来成一个全是汇编的代码,如:
procedure Test; assembler;
asm
//do something 纯汇编代码
end;
- 代码从IA-32移植到Intel 64并不仅仅是简单的复制代码,考虑到架构的特殊性,如指针的大小及对齐,你需要查询新架构的使用说明,如果你想编译一份代码为不同的CPU架构的话,那就用Define吧
- 寄存器对应的表如下:
32位 | 64位 |
---|---|
EAX | RAX |
EBX | RBX |
ECX | RCX |
EDX | RDX |
EBP | RBP |
ESI | RSI |
EDI | RDI |
ESP | RSP |
WinAPI相关
- 如果你传了指针给SendMessage/PostMessage/TControl.perform,那WParam跟lParam参数必须设置成WPARAM/LPARAM,而不是Integer/LongInt.
正确的写法:
SendMessage(hWnd, WM_SETTEXT, 0, LPARAM(@MyCharArray));
错误的写法:
SendMessage(hWnd, WM_SETTEXT, 0, Integer(@MyCharArray));
- 在处理GWLP_HINSTANCE, GWLP_ID, GWLP_USERDATA, GWLP_HWNDPARENT 和 GWLP_WNDPROC作为它们返回指针或句柄的时间 用SetWindowLongPtr/GetWindowLongPtr替换SetWindowLong/GetWindowLong,同时给SetWindowLongPtr传递指针时需要显示定义为Long_Ptr,而不应该是Integer或LongInt.
正确的写法:
SetWindowLongPtr(hWnd, GWLP_WNDPROC, LONG_PTR(@MyWindowProc));
错误的写法:
SetWindowLong(hWnd, GWL_WNDPROC, Longint(@MyWindowProc));
- 给TMessage.Result赋值时应该定义成LRESULT,而不是Integer/LongInt.
正确的写法:
Message.Result := LRESULT(Self);
错误的写法:
Message.Result := Integer(Self);
- 所有的TWM..windown消息的结构体都应该用正确的
Msg: UINT; wParam: WPARAM; lParam: LPARAM; Result: LRESULT)
其它
- 代码里用到的其它的第三方的控件是否支持64位,如果不支持的话,考虑升级或换成另一个控件
- 64位的obj文件,如果你的64位程序需要链接第三方的.obj文件,你需要注意你需要一个64位的.obj文件。
- TFile:文件句柄,是32位的,需要替换成THandle.
以上的内容参考的是:http://docwiki.embarcadero.com/RADStudio/Seattle/en/Converting_32-bit_Delphi_Applications_to_64-bit_Windows, 再加上自己遇到的问题整理得来。