delphi2010是delphi所有版本的分水岭,其中2010—xe10.2之间版本上的代码都有比较好的兼容性,基本上都能直接进行编译,不需要过多修改,但d7距d2010跨度4个版本以上,新版本除了增加新功能函数外,对原有的vcl控件也进行了优化和增强,并且支持64位、跨平台开发、多语言、直接支持跟随系统风格样式,所以升级相对有些麻烦,但却有价值。

RZ、FR、EHLIB 等常用控件都有跟随delphi推出了版本,d7的绝大部分代码也可以直接在d2010以上版本中进行编译,最需要处理的问题主要在新版本字符串类型方面的变化。

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兼容而存在,且没有引用计数,性能低下。 
 
https://user.qzone.qq.com/21968578/blog/1492132900

升级d7的代码到2010以上版本注意事项(SetLength的参数就是字符长度,而不是字节长度,但Move函数要改)的更多相关文章

  1. 升级时出现:请先升级 UCenter 到 1.6.0 以上版本。

    有的站点UCenter升级完成后仍然提示请先升级 UCenter 到 1.6.0 以上版本的现象,下面分享下UCenter版本号不正确的原因和处理办法,可能有以下的几个文件和处理办法: 一.UCent ...

  2. Android 一s个相对完整的自动升级功能实现代码

    由于项目的需要最近做了一个关于Android自动升级的功能,下面将贴出Android手机客户端的完整代码.这段代码参考别的代码居多,由于不满足需求,所以自己仅仅改了一些需要变动的内容,其他功能都是按照 ...

  3. Android 一个相对完整的自动升级功能实现代码

    由于项目的需要最近做了一个关于Android自动升级的功能,下面将贴出Android手机客户端的完整代码.这段代码参考别的代码居多,由于不满足需求,所以自己仅仅改了一些需要变动的内容,其他功能都是按照 ...

  4. 代码演示C#各版本新功能

    代码演示C#各版本新功能 C#各版本新功能其实都能在官网搜到,但很少有人整理在一起,并通过非常简短的代码将每个新特性演示出来. 代码演示C#各版本新功能 C# 2.0版 - 2005 泛型 分部类型 ...

  5. Installshield停止操作系统进程的代码 --IS6及以上版本适用

    原文:Installshield停止操作系统进程的代码 --IS6及以上版本适用 setup.rul的代码 Code;end;///////////////////////////////////// ...

  6. vue(element)中使用codemirror实现代码高亮,代码补全,版本差异对比

    vue(element)中使用codemirror实现代码高亮,代码补全,版本差异对比 使用的是vue语言,用element的组件,要做一个在线编辑代码,要求输入代码内容,可以进行高亮展示,可以切换各 ...

  7. C#返回字符串的字节长度,一个中文算两个字符的代码

    如下代码段是关于C#返回字符串的字节长度,一个中文算两个字符的代码. public static int GetLength(string str) { if (str.Length == 0) re ...

  8. UNIGUI换版本注意事项

    比如UNIGUI换版本注意事项 许多人在更换UNIGUI版本时,会遇到各种问题,报各样错.比如下面的: 然后便不知所措,怀疑是UNIGUI新版本有问题——不能安装成功.其实不然. 下面是正确的解决方法 ...

  9. 《超实用的Node.js代码段》连载一:获取Buffer对象字节长度

    我们知道Node.js框架下的Buffer对象能够对二进制数据提供很好的支持,那么获取一个Buffer对象真实的字节长度则是必须要用到的功能了.Node.js框架为开发人员提供了一个Buffer.by ...

随机推荐

  1. github push出错(1)You can't push to git:// Use https://

    fatal: remote error: You can't push to git://github.com/niexiaobo/remote.git Use https://github.com/ ...

  2. 进入Erlang的世界

    http://erlang.group.iteye.com/group/wiki/1407-to-enter-the-world-of-erlang 进入Erlang的世界 作为程序员,我们曾经闻听很 ...

  3. hadoop 3.x Replication与Availability不一致

    看下面的文字前先确保你的Replication值不大于你设置的虚拟机数量 如图,显示的副本数为3,但是实际可用的只有一台机器,查看了下hadoop003,hadoop004两台机器,果然没有存储数据, ...

  4. apt-get install 的参数(add-apt-repository)

    apt-get install 是 ubuntu 下的软件安装命令. sudo apt-get -y install: -y:yes,在命令行交互提示中,直接输入 yes: 1. 使用 add-apt ...

  5. Logical partitioning and virtualization in a heterogeneous architecture

    A method, apparatus, and computer usable program code for logical partitioning and virtualization in ...

  6. python 简单的Socket编程

    python 编写server的步骤: 1第一步是创建socket对象.调用socket构造函数.如: socket = socket.socket(family, type ) family参数代表 ...

  7. eclipse中JUnit工具的使用

  8. 狄利克雷过程(Dirichlet Process)

    0. 引入 现观察得到两个样本 θ1,θ2,来推测它们可能来自的分布: 假设来自于连续型概率密度函数, θ1,θ2∼H(θ) 则 θ1,θ2 相等的概率为 0,p(θ1=θ2)=0 概率为 0,不代表 ...

  9. handler looper和messageQueue

    一.用法. Looper为了应付新闻周期,在创建过程中初始化MessageQueue. Handler在一个消息到当前线程的其他线程 MessageQueue用于存储所述消息 Looper其中线程创建 ...

  10. 给CentOS 6安装Tomcat 7,从一开始

    由于给企业培训以及前面几年使用PHP太多了,这次server逐步转为使用JavaEE来搭建. 下载的JDK 7.8已经出来了,可是不太熟悉,所以还是下载7版本号.这里怎样安装JDK7不讲了. 当前最新 ...