在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
这两天把一个使用Delphi2007开发的30万行左右的项目,成功升级到了Delphi2010。升级途中很艰辛,总结了 以下经验与大家分享。另外,工程中使用的第三方组件,由于官方没有发布For Delphi2010的更新,我也顺便修改了。有需要的联系我。修改的第三 方组件列表见文章尾部。
1,PChar因为Delphi不支持无类型指针的算术运算,很多程序员使用 PChar来代替Pointer,即使指针指向目标并不是PAnsiChar。 考虑如下代码:
var
P:PChar; Buffer:Pointer; begin GetMem(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)来获取,这是行不通的。 考虑如下代码:
var
P1,P2:String; begin P1:='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下运作了,有需要的联系我。 |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论