这两天把一个使用Delphi2007开发的30万行左右的项目,成功升级到了Delphi2010。升级途中很艰辛,总结了 以下经验与大家分享。另外,工程中使用的第三方组件,由于官方没有发布For Delphi2010的更新,我也顺便修改了。有需要的联系我。修改的第三 方组件列表见文章尾部。

1,PChar

因为Delphi不支持无类型指针的算术运算,很多程序员使用 PChar来代替Pointer,即使指针指向目标并不是PAnsiChar。

考虑如下代码:

varP:PChar;Buffer:Pointer;beginGetMem(Buffer,255);P:=Buffer;p^:=#1;Inc(P);p^:=#2;FreeMem(Buffer,255);end;

在2010中PChar已经不再表示PAnsiChar而是表示PWideChar,如果依然这样写,运行时很可能会得到一个内存访问错误。因为每 次Inc(P),实际上指针向前移动了2字节,因为SizeOf(WideChar)=2,Inc(P)相当于 P:=P+SizeOf(WideChar)。

解决方法是把PChar替换成PAnsiChar

2,Move FillChar CopyMemory

这些函数依赖的是字节长度,往往我们直接使用Length(Str)来获取,这是行不通的。

考虑如下代码:

varP1,P2:String;beginP1:='test';SetLength(P2,Length(P1));Move(P1[1],P2[1],Length(P1));

在2010中String默认映射到UnicodeString,单个字符是2字节,所以上文中P1实际占用了8字节内存,而传给Move函数的长 度只有4字节,最终结果是P2="te"。

解决办法1:

修改String为AnsiString,该方案虽然可行,但你的程序就享受不到Unicode待遇了。

解决办法2:

SetLength 函数不要修改,因为他的长度参数是字符长度,而不是字节长度。

Move函数的最后一个参数 Length(P1) 修改成 Length(P1)*SizeOf(Char)

注意:不要偷懒使用万一老师说的ByteLength函数,该函数并没有For AnsiString的重载,编译器会 把参数隐式转化为UnicodeString然后,ByteLength函数计算UnicodeString的长度。例如:一旦你不小心传入了一个 AnsiString类型长度为4的字符串,函数会返回8,而不是你期望的长度4。

3,Key in ['a'..'z','B','C']

这类代码最好替换成CharInSet(Key,['a'..'z','B','C']) 不然会当作AnsiChar处理。

4,WideString

代码中的所有WideString都考虑替换成String,现在 WideString只是为了与COM兼容而存在,且没有引用计数,性能低下。

5,Tnt控件

如果你的工程使用了Tnt控件或以前的WideTextPos WideStringReplace之类的东西都替换成标准的吧,不用曲线救国了。

待续…………

---------经过修改,可以在Delphi2010下运作的第三方组件--------------

1,PNGDelphi

2,EmbeddedWB

3,SynEdit的语法高亮组件 unihighlighter

4,JEDI Win32API Header

这些组件现在可以在Delphi2010下运作了,有需要的联系我

6,引用AnsiStrings单元

如果你有必要使用 AnsiLowerCase AnsiCompareStr之类的函数,一定要引用AnsiStrings单元。

如果你不引用该单元,即便编译不报错,你实际上是用的还是Unicode版本的函数,会有隐式的转化。不信你打开参数自动完成,看看IDE提示给你的类型是什么?天啊AnsiLowerCase参数竟然还是String,而不是AnsiString。看来Delphi2010太迫切的要抛弃Ansi字符串了,以至于你不引用AnsiStrings单元,所有Ansixxxx函数实际上还是Unicode版本。

7,AnsiCopy AnsiPos AnsiDelete

不要用AnsiCopy AnsiPos AnsiDelete,因为Copy Pos Delete三个函数已经有了For Ansi的重载。

8,把Char转化为小写用什么?

答案:试试看Character单元的新函数 ToUpper ToLower。以前我都是用System里面的UpCase函数,现在依然可用不过却找不到LowCase DownCase之类的函数,困扰我好久好久。索性全使用Character单元提供的新函数吧。

9,编译期警告:[DCC Warning] Unit1.pas(31): W1057 Implicit string cast from 'AnsiString' to 'string'

如果你的代码中包含了两种字符串(Unicode、Ansi)之间进行隐式转化的时候就会出现该提示。

如下代码就会触发该警告:

view sourceprint?
1 var
2   Unicode:String;
3   Ansi:AnsiString;
4 begin
5   Ansi:='test..';
6   Unicode:=Ansi;

把旧版本的Delphi项目升级到2010,我通常都是借助编译警告来快速寻找需要改动的部分。通常你可以把赋值双方都声明为String(默认影射到UnicodeString),就可以避免该警告。但如果你确定必须在此处保留Ansi并进行转化的时候,建议你显式的转化他们(例如:Unicode:=String(Ansi);),这样可以避免该警告,方便你在升级过程中继续寻找其他需要修改的地方。

10,Readln Writeln 写入文件时候要注意

如果你传给Writeln一个AnsiString,那么它也会在文件中写入AnsiString,那么你读取得时候就必须传给Readln一个AnsiString的类型,否则就是乱码。例如旧工程的配置文件是Ansi的,而你已经把相关读取配置的代码升级为支持Unicode,那么运行工程前你首先要用记事本之类的工具把配置文件另存为成Unicode编码。当然你还要注意跳过Unicode文件头的两个字节FE FF。

11,别再用String来操作二进制数据了

一定要记住String只是字符串,不要把它当作缓冲区、内存流使用。我的项目中,有很多地方是使用字符串来处理二进制数据,导致在本次升级中颇为费脑。如果当时用TBytes或TStream就好了。

反面教材:

view sourceprint?
1 var
2   Int1,Int2,Int3,Int4:Integer;
3   Buf:String;
4 begin
5   SetLength(Buf,12);
6   Move(Int1,Buf[1],SizeOf(Integer));
7   Move(Int1,Buf[5],SizeOf(Integer));
8   Move(Int1,Buf[9],SizeOf(Integer));
9   Buf:=Buf+'前面有3个Integer。';

12,还是PChar

注意在2010中是这样的:

PChar= Pointer to a WideChar array;

PAnsiChar = Pointer to a AnsiChar array;

如果你还像是在Delphi 7中那样:PChar(AnsiString)那后果过是很严重的

项目升级到Delphi 2010总结相关推荐

  1. Delphi7升级到Delphi 2010、Delphi XE、Delphi XE2总结 .

    Delphi7升级到Delphi 2010.Delphi XE.Delphi XE2总结 这两天把一个使用Delphi2007成功升级到了Delphi2010.升级途中很艰辛,总结了 以下经验与大家分 ...

  2. .Delphi7升级到Delphi 2010、Delphi XE、Delphi XE2总结

    转自: http://guanyue7613.blog.163.com/blog/static/885147420120404747235/ 这两天把一个使用Delphi2007成功升级到了Delph ...

  3. [转]Delphi 2010 3513正式版破解

    原文地址: http://www.cnblogs.com/tc310/archive/2010/05/08/1730300.html http://www.kucol.com/html/NEws/ye ...

  4. RAD Studio/Delphi 2010 3615下载+破解

    RAD Studio/Delphi 2010 3615下载+破解 官方下载地址: http://altd.embarcadero.com/download/RADStudio2010/delphicb ...

  5. 如何将ASP.NET MVC2项目升级到MVC 3 RC

    微软在10号发布了ASP.NET MVC3的发布候选版(RC:Release-candidate),该版本提供了Razor视图引擎的智能感知等功能,并同样具备Online许可.眼馋的同学是不是已经迫不 ...

  6. Delphi 2010 安装及调试

    呵呵,毫不客气地说,Delphi 2010 这个版本可以算是 Delphi 的一个"里程碑",为什么这么说?因为这个版本实现了几个 Delphi 应该有却一直没有的功能 Delph ...

  7. Delphi 2010 refactor / refactoring 重构不能使用的原因以及解决

    delphi 2010 refactor / refactoring 重构不能使用. 经过实验的确是DelphiDistiller上的设置贴心的过头的原因. 一切的罪魁祸首就是"Don't ...

  8. 将 Net 项目升级 Core项目经验:(一)迁移Net项目为Net Core\Standard项目

    迁移Net项目为Net Core\Standard项目 背景: 我们公司内部有自己ORM开发框架,最新因为需要将系统迁移到国产服务器上,所以首先需要将最基础的ORM框架改造可以运行在国产服务器上.对于 ...

  9. 借助 SAP 电商云 Spartacus UI 提供的 Schematics 辅助您的前端项目升级

    将 Spartacus 升级到新的主要版本(例如,从 3.x 到 4.0)时,Spartacus 迁移机制会自动修复新版本中修改或删除的代码. 当您处理功能或错误,或对 Spartacus 源代码进行 ...

  10. C# 利用.NET 升级助手将.NET Framework项目升级为.NET 6

    概述 .NET6 正式版本已经发布有一阵子了,今天我就体验一下如何将.NET Framework的项目升级为.NET 6. 升级条件: Windows 操作系统 .NET 6 SDK Visual S ...

最新文章

  1. 深度丨《主算法》作者 Pedro Domingos 谈机器学习十大误解
  2. Ural(Timus) 1146. Maximum Sum
  3. SQL应用中级指南 Part4:(数据字典)
  4. 2021算法竞赛入门班第八节课【数学】习题
  5. ai如何置入_AI基础教程51:文字(一)文本的置入与导出
  6. python 文本转json_在python中将文本文件转换为json
  7. 祝贺|合肥.NET俱乐部第二期技术沙龙活动圆满成功
  8. arm nodejs_ARM发布Cortex A78C增强版大核架构
  9. (王道408考研操作系统)第三章内存管理-第一节6-1:非连续分配管理方式之基本分页存储管理
  10. Java中PO、DO、TO、DTO、 VO、 BO、POJO 、DAO的概念
  11. 《31天重构》4:下置方法
  12. 例解List<Map<String, Object>>存放的对象问题
  13. keras中无法用save保存模型的问题
  14. 史上最全的面试宝典,让你轻松入职
  15. 第二章.JSP/Servlet及相关技术详解
  16. Kotlin 官方参考文档 中文版_kotlin-reference-chinese.pdf
  17. java case 字符_Java中Switch Case使用字符串
  18. 微信小程序使用sass
  19. Android开发工具类集锦
  20. redmi k60参数 红米k60怎么样 redmi k60优缺点

热门文章

  1. 最新可使用在线音乐网站+多解析源码
  2. MATLAB添加工具包
  3. Java程序设计教程(第3版)雍俊海 全书例程-1
  4. 编程语言和javascript
  5. win98 支持html5,win98 ghost ghost在WIN98怎么使用
  6. 这可能是最全的JAVA入门教程 ~
  7. linux 下tftp服务器搭建,CentOS 6下搭建TFTP服务器
  8. P2P终结者 操作用法(如何限速)
  9. Qt setFocus
  10. linux远程映射usb设备,Linux 系统下USB端口映射