delphi32位程序转换成64位程序攻略
2016-05-19 14:30
344 查看
如果你有一个32位的Delphi程序要升级成64位,可以参考下面的攻略进行升级。
先升级成Unicode版本
在IDE环境下打开你的32位工程,添加并激活64位的平台,并且编译你的工程为64位的。
查找并处理如下的事项(指针的操作,NativeInt的大小,汇编的代码)
指针的操作
在你的代码里查找以下指针相关的操作:
指针的大小改变了
在32位的程序中, 指针是4bit,但是在64位程序中,指针是8bit.
你可以假定
如果你想增加指针的话,要意识到,64位的指针操作跟32位的指针操作是不一样的,所以你需要调整你的代码
正确的如下:
兼容的写法:
错误的写法:
你不能假定
正确的写法应该是:
错误的写法是:
关于更多关于64位程序上的指针操作,请参考MSDN上的文章
整型类型
在64位的平台中,Integer依旧是4bit,但是NavtiveInt的大小改了。
在64位中,NativeInt大小是8Bit
在32位中,NativeInt大小还是4Bit
内联汇编
如果你的代码含有内联汇编代码,你需要检查汇编的代码,并做如下的修改:
64位的代码是不支持汇编跟pascal代码混合的,你需要把汇编代码换成pascal代码或者把汇编的代码提出来成一个全是汇编的代码,如:
代码从IA-32移植到Intel 64并不仅仅是简单的复制代码,考虑到架构的特殊性,如指针的大小及对齐,你需要查询新架构的使用说明,如果你想编译一份代码为不同的CPU架构的话,那就用Define吧
寄存器对应的表如下:
WinAPI相关
如果你传了指针给SendMessage/PostMessage/TControl.perform,那WParam跟lParam参数必须设置成WPARAM/LPARAM,而不是Integer/LongInt.
正确的写法:
错误的写法:
在处理GWLP_HINSTANCE, GWLP_ID, GWLP_USERDATA, GWLP_HWNDPARENT 和 GWLP_WNDPROC作为它们返回指针或句柄的时间 用SetWindowLongPtr/GetWindowLongPtr替换SetWindowLong/GetWindowLong,同时给SetWindowLongPtr传递指针时需要显示定义为Long_Ptr,而不应该是Integer或LongInt.
正确的写法:
错误的写法:
给TMessage.Result赋值时应该定义成LRESULT,而不是Integer/LongInt.
正确的写法:
错误的写法:
所有的TWM..windown消息的结构体都应该用正确的
其它
代码里用到的其它的第三方的控件是否支持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, 再加上自己遇到的问题整理得来。
先升级成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 |
如果你传了指针给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, 再加上自己遇到的问题整理得来。
相关文章推荐
- delphi ios grid BindSourceDB bug
- delphi中Message消息的使用方法
- 减小Delphi XE5编译出来的程序体积
- 减小Delphi2010程序的尺寸(关闭RTTI反射机制)
- DELPHI 中 Window 消息大全使用详解
- Delphi中的消息处理
- Delphi中操作INI文件
- Delphi Berlin 窗体代码分离风格 回到Delphi7传统风格
- delphi中如何将string类型的字符串数据转化成byte[]字节数组类型的数据
- Delphi Berlin 10.1 for iOS 成生 info.plist 顺序改变了
- Delphi Integer 转成单字节
- delphi const的用法
- Delphi 快捷键
- delphi中Treeview的使用介绍
- [付费视频]Delphi视频Android开发使用静态库(A)和动态库(SO)
- Delphi 释放数组中的数据
- delphi 10.1 berlin datasnap提交clientdataset.delta报:invalid variant type conversion(类型转换错误)问题的解决
- delphi中将 4 个 Byte 合成 1 个 Integer 的五种方法
- Delphi中@,^,#,$分别表示什么?
- Delphi中@,^,#,$特殊符号意义