Delphi的一个基本事实是,全世界存在使用较旧版本Delphi编写的大量应用程序软件。尤其是经典的Delphi 7,然而现在是2021年,是时候升级到Delphi 10.4.1新版本了。每天都会有人问我有关从15到20年的旧版本Delphi迁移到最新版本Delphi的问题。值得庆幸的是,Delphi使数十年来的迁移相对容易,但是,这并不意味着轻松!
本页面旨在解决最常见的陷阱,这些陷阱可能是从2009年之前的任何版本的Delphi(包括Borland版本)过渡到现代的Embarcadero Delphi版本的陷阱。
我希望此页面成为一份生动的文档,随着时间的推移我将对其进行更新以包括我发现的所有陷阱。我还将致力于为迁移过程添加提示和技巧,并提供相关文档的链接。
如果您发现其中未包含的内容,请注册并发表评论,我可能会将其集成到此页面中。
跨平台的期望。
在开始研究版本迁移的常见陷阱之前,我想花一点时间(实际上是一两个好页面)来讨论现代Delphi版本经常被误解的功能。如果您对将代码迁移到移动平台或MAC桌面没有兴趣,请继续跳到标题为“ Windows 64位迁移”的部分,我们将从那里开始。
现代新版本 Delphi能够编译代码以定位Windows 32位和64位,MAC OSX,Android和iOS。这个事实导致人们期望Delphi可以使用您的Windows应用程序,并以某种方式使其跨平台。这不是真的!如果它是真的,那将是某种真正的魔法,但事实并非如此。事实是这样:Delphi的现代版本可以为Windows,Mac OSX,Android和iOS编写应用程序。
如果您的应用程序最初是为Windows编写的,则它将使用Win32 API。如果您的应用程序是VCL应用程序,则它使用Win32 API。在Mac OSX,Android和iOS上不可用的一件事是Win32 API。看看我要去哪里?如果不进行重大代码修改,您的应用程序将无法在其他平台上运行。值得庆幸的是,虽然Delphi不会为您神奇地解决此问题,但仍有一些辅助工具可以帮助您…
跨平台应用程序是针对名为FMX的新框架编写的。(以前称为FireMonkey,FMX = FireMonkey X平台)。
FMX框架不依赖Win32 API及其控件,而是实际上使用OpenGL或DirectX打开渲染上下文,并将控件直接渲染到该API。这样,可视控件就可以跨平台。FMX框架具有Delphi随附的绝大多数VCL控件的镜像控件,例如,VCL和FMX都具有TEdit控件,它们都具有TButton控件,依此类推。
有一个名为“ Mida转换器”的工具(请参见此处),它可以打开您现有的VCL表单(.dfm文件),并对其进行修改以使用FMX版本的控件而不是VCL控件。这样,该表格就可以有效地从VCL移植到FMX,因此可以用于Windows以外的平台。但是,这种方法仍然存在一两个陷阱。Mida转换器仅是复制/替换宏工具,如果您使用的控件不是VCL的一部分(例如第三方控件),则Mida转换器无法迁移这些控件,您必须跟踪该控件的FMX版本(如果存在),或从另一个第三方供应商那里替代FMX。
这样的FMX组件供应商之一是TMS软件:https : //www.tmssoftware.com/site/tmsfmxpack.asp
跨平台的其他注意事项
从仅Windows应用程序迁移到跨平台解决方案时,除了视觉控件外,还有其他一些注意事项。首先,除Windows之外,Delphi支持的所有平台都以某种方式基于unix / linux变体,因此都基于POSIX。因此,需要考虑一些事情……
关于跨平台迁移的最终决定和一些希望。
大多数错误地期望Delphi将其应用程序迁移到其他平台的开发人员,也缺少一个关键的重要细节,因为他们实际上可能根本不想将其应用程序迁移到那些平台!如果您在其中,请和我在一起。移动屏幕很小,并且用笨拙的手指来操作,而不是使用鼠标的优雅精度。与台式机相比,移动设备还缺少资源(RAM,磁盘空间,CPU周期等)。如果您将VCL应用程序直接迁移到FMX并将其部署到移动设备上,则很有可能在如此小的屏幕上无法使用,或者由于缺少设备资源而表现糟糕。
在许多情况下,更明智的策略是考虑为您的移动应用程序启动一个全新的项目。这个“伴侣应用程序”项目仍然可以使用您大部分的非可视代码,毕竟仍然很麻烦,但是您可以将新项目限制为仅在移动设备上有意义的那些功能。而且,Delphi附带了一些类,以帮助将您的移动伴侣应用程序集成到现有桌面应用程序旁边的网络中。例如,使用应用程序绑定 类,您的移动应用程序可以直接调用桌面应用程序内的操作,并双向共享数据。
Windows 64位迁移。
从Windows 32位到Windows 64位的迁移要比迁移到完全不同的平台少得多,但是我在这样做时遇到了一个陷阱。
假设整数和指针具有相同的大小(32位),这在Delphi开发人员社区中已成为相当普遍的做法,并且鉴于Delphi中的类实例实际上只是一种特殊的指针,您可以有效地类型转换为一个整数类,用于存储在整数数组中。除此之外,VCL的可视类的.TAG属性也是32位整数,并且可能已被某些类型转换拼图工具用作对象指针。好吧,如果您已完成此操作,或者正在编译执行此操作的第三方源,则现在遇到了问题。在Windows 64位下,指针当然是64位宽,但是整数类型仍然是32位宽。您需要更改此代码以说明不同的数据类型。添加了一些新的整数数据类型以辅助操作。
现在,在开始编写64位代码之前,请问自己是否确实需要这样做?对64位代码有很多常见的误解,并且升级到它通常没有什么好处。我们所处的情况与计算机从8位时代迁移到16位或从16位时代迁移到32位时代的情况不同。
您会看到,将应用程序升级到64位的最常见原因之一是为应用程序提供了更多可寻址的内存空间。对于8位,您只能寻址256字节的RAM,并且要实现更多功能,需要某些存储体切换操作,这会花费处理时间。使用16位可以使事情有所改善,您可以处理高达64k的RAM,并且仍然需要进行组切换以利用更多的内存。进入32位模式,您可以寻址4GB的巨大RAM!即使到了今天,这对于绝大多数应用程序来说也足够了,Windows 32位实际上只允许您的应用程序在任何情况下都使用2GB的空间,而将其他2GB的空间保留给内核。
除少数例外,如果您的应用程序使用的内存超过2GB,则可能是您做错了什么。
例如,如果您要从数据库中拖回数百万行的数据,您是否真的需要将所有数据保存在RAM中?出于显示目的,即使您可以在屏幕上塞满所有的行,也没有人希望一次看到这几百万行,因此缓存到磁盘文件是一个更好的策略。本质上,绝大多数应用程序将使用2GB-4GB的可寻址RAM,因此这可能不是升级的理由。
速度呢?嗯,64位处理器实际上并没有比32位处理器快,它们的速度优势来自能够处理更大的整数。因此,如果您的应用程序需要处理大量数据,则升级到64位可能会提高性能,但是,如果您的代码尚未使用64位数值数据类型,则必须遍历所有代码并用64位等效项替换32位类型。为64位目标重新编译相同的应用程序不会削减它。
最终,根本没有充分的理由进行升级,并且请记住,因为所有指令操作数和编码都更大,所以64位可执行文件明显大于32位。进行跳转之前,请确保您需要64位。
Unicode迁移。
可怕的unicode迁移,似乎以某种方式使许多开发人员感到恐惧!实际上,Unicode并不像听起来那样可怕,在所有已迁移到unicode时代的编译器产品中,Delphi是最简单的产品之一。有些项目需要零更改,而编译器只需为您处理,而其他项目则可能需要一些更改,而一些项目则需要很多更改。
有一个工具(Unicode统计工具)可以帮助您确定需要进行的更改数量。您将此工具指向您的项目和单元文件,它将为您执行代码的统计分析,并为您提供所需工作量的度量。
在大多数情况下,编译器会强制转换字符串类型,以便您的代码继续按预期进行编译和运行。不正确的情况通常包括以下情形:
有关使用Delphi进行unicode迁移的更多详细信息(远远超出此处介绍的范围),可以在以下 网址找到:http://www.embarcadero.com/rad-in-action/migration-upgrade-center
实际数据类型。
在版本迁移的讨论中经常被忽略的是,旧的“真实”数据类型已从编译器中删除,并被替换为“双重”数据类型的别名。它经常被忽略的原因是它很少出现问题,但是,与unicode迁移一样,在反序列化由使用早期Delphi版本编译的应用程序序列化的数据时,这一小小的改变也可能引起人们的注意。如果在代码中使用实数,请抬头。
BDE不见了!
不要惊慌 BDE实际上还没有完全消失,但是已经过时了。默认情况下,BDE不再随Delphi一起提供,但是您可以在购买Delphi后从您的EDN帐户单独下载。原因是BDE很旧,缺乏unicode支持,并已被性能优越的FireDAC取代。
如果您的应用程序使用了BDE,建议您使用reFind工具将项目迁移到FireDAC。(使用reFind从BDE迁移到FireDAC / David I到FireDAC和Interbase的迁移 )该工具几乎可以为您完成工作!我还没有听说过任何实际遇到困难的人,因此,如果您遇到困难,尤其是找到解决方案,请考虑注册并在注释中留下注释!
还在使用paradox吗?
一些较旧的Delphi应用程序仍在使用paradox数据库。不幸的是,该数据库不再受支持,因此您可能不得不迁移到另一个数据库引擎。如果您只使用了paradox来满足数据库需求,那么您可能还想学习一点SQL和DDL,以便利用更现代的数据库。这样的学费超出了本页面的范围,但是,您会在网上找到一些出色的教程,老实说,这将是值得您花费的时间!
Marco Cantu从Paradox和dBase进行迁移。
W3Schools SQL教程。
第三方组件。
我为您保存了最好的直到最后!有些开发人员喜欢它们,有些则讨厌它们,但是在两所学校中,您可能都至少使用了某些第三方组件。不喜欢第三方组件的两个最大原因是:
但是,如果您仔细选择了供应商,您会发现一个出色的第三方组件集,需要经常维护,并且可以提供稳定的高质量组件,从而从根本上增强Rad Studio / Delphi的性能,进而提高您的产品质量。因此,我属于“爱情”类别!
不管您在哪方面,如果使用了第三方组件,在将项目从较早的Delphi版本迁移到新版本之前,都需要使用最新版本的组件。Embarcadero正在努力通过其新的GetIt功能来提供帮助,该功能提供了第三方组件存储库,可以在IDE内自动安装多个流行的组件集!
请参阅:RadStudio XE10.4.1获取组件存储库!
该存储库中的组件集合很小,但是正在增长,Embarcadero甚至资助了维护者已经离开或放弃其产品的通用组件集的更新。Embarcadero还确保存储库中的组件将使用最新的Delphi版本进行更新,因此无法找到自己以后不再设置该组件的位置。
在撰写本文时,GetIt存储库中安装的组件包括:
Abbrevia 10.0
AerServ 10.0
AsyncPro for VCL 1.0
Boos 1.39 / 1.55
Essentials TurboPack for VCL 1.0
ICS for FMX和VCL 8.16
Lockbox 2.0
Lockbox 3.5
现代化的AggPas VCL
OmniThread库3.04a
OnGuard for FMX 1.0
OnGuard for VCL 1.0
Orpheus for VCL 4.0.8
PowerPFD for VCL 1.0
适用
于VCL的SynEdit 1.0 SysTools 4.04
适用于VCL 5.5的VirtualTree
如果您尚未使用XE8,则还可以从此处获取XE7的以下几个组件: Romans Blog
如果不幸的是您不再拥有第三方组件,但是您明智地购买了源代码,那么更新该代码以在最新版本的Delphi中进行编译通常就比较简单了。例如,最近我发布了Advantage数据库组件的更新,因为SAP尚未针对Delphi XE8对其进行升级。我必须在代码中进行的唯一真正的更改就是更改条件定义以包括当前的编译器版本号,仅此而已!
另外,如果您曾经使用过开源的组件,但似乎已无法维护,则请务必查看GitHub,以查看该项目是否已迁移。其中很多都是没有警告或更新的。
最后,如果您拥有不再维护的第三方组件,并且您没有源代码,那么很抱歉,但是您不走运,这就是泰山老父强烈建议一定要使用带源码的第三方组件的原因。几十年来,一些组件公司已经离开了Delphi社区,这是不可避免的。如果要升级,则必须从其他供应商处找到等效的组件,然后修改代码以适合这些组件。
我的迁移需要多长时间?
它大约需要完成一半任务的两倍。抱歉,要迁移升级的项目千差万别。您可能没有碰到上述任何迁移陷阱,或者可能很不幸无法实现所有这些陷阱。
我的一些C ++客户报告说平均每天需要转换60,000行代码的旧版C ++ Builder项目。虽然C ++ Builder本身就是它自己的产品,但它也是基于VCL和FMX并经过unicode迁移的,因此这些数字可能是一个含糊的指南。确保使用上面链接的Unicode迁移统计工具,并且要保守但不要担心迁移。
结论。
如果这看起来像是一个冗长的页面,请记住,我已经谈到了本来可以忽略的跨平台迁移,并且我们正在讨论使用Delphi进行几十年版本的迁移。从一个版本到另一个版本,Delphi的断层很小,但是它是一种成熟的产品,必须与时俱进。
现代Delphi在IDE中具有很多功能(至少在我看来)是首屈一指的。它具有您期望的所有现代语言功能,并且能够在台式机,多层企业,云和移动开发空间中立于不败之地。如果您使用的不是最新版本,则会错过很多东西!希望您的迁移进展顺利。
谢谢阅读!Delphi万岁!!