分享
 
 
 

升级到Delphi 6 - 兼容性问题之二

王朝delphi·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

一. 潜在的二进制Form文件的不兼容

过去,新版本Delphi创建的二进制Form文件(或称DFM文件)可以被老版本的Delphi读取。但是现在不行了。某些二进制Form文件可能不能被老版本正确的读取,其原因是Delphi 6内部的字符串的流化和原先不同。过去,流化操作假设一个本地特殊的字符集。而现在新的流化操作假设字符集为UTF-8。由此带来的问题就是,如果Delphi 6的二进制Form文件中包含有码值大于127的字符出现(比如版权符®),则该文件就不能被Delphi 的老版本正确读取。

如果你想在老版本的Delphi 中打开Delphi 6 的Form文件,那么请先将该Form文件存为文本格式而非二进制格式。

Potential binary form file incompatibilities

In the past, binary form files (or DFM files) created with newer versions of Delphi could be read by older versions. This is no longer true in Delphi 6; some binary form files may be read incorrectly because of the way that Delphi 6 performs internal string streaming. In the past, streaming was performed assuming a locale specific character set. Now streaming assumes that the character set is UTF-8. As a consequence, if there are characters with a code greater than 127 (such as the copyright symbol ? in a Delphi 6 binary form file, that file cannot be read by older versions of Delphi.

If you intend to use a Delphi 6 form file (including older form files imported into and modified with Delphi 6) in an older version of Delphi, the file should be saved in text format instead of binary format.

二. 有关可赋值的常量

编译宏$WRITEABLECONST现在的缺省值改为关,这是为了防止Delphi的工程中运用可赋值的常量。可赋值的常量,也就是定义一个常量,但是却允许在运行期间改变其值。例子如下:

const

foo: Integer = 12;

begin

foo := 14;

end.

在以往的Delphi版本中,有这么一个特性:常量不是真正的常量。使用编译宏$WRITEABLECONST OFF,则以上的代码中的Begin和End之间的Foo的赋值将引发一个编译错误。若要避免它,只需将Foo的声明改为 var。

你可能有将常量用作一个可以初始化的局部变量的代码,比如:

procedure MyProc;

const

somedata: Integer = 12;

begin

Inc(somedata, 3);

end;

你要做的是将局部常量移到过程的外部声明,使其成为一个全局的变量。然后代码变为:

var

somedata: Integer = 12;

procedure MyProc;

begin

Inc(somedata, 3);

end;

对于过度依赖于常量的代码(比如ActiveX 控件的包装器),可以通过在源文件中插入一个{$WRITEABLECONST ON}的编译命令来修正。这一特性,在RTL, VCL, CLX,和 DB 等核心的源代码中被禁止使用,但是在周边的单元比如ActiveX 控件的包装器中倒可以接受。

总而言之,你应该意识到“可赋值的常量”这个说法的自相矛盾。Delphi的以往版本中的这一特性,只是为了与老的16位的编译器的兼容而保留,但现在对于Delphi的开发者来说已经毫无意义了。要养成好的编程习惯,尽量避免使用可赋值的常量。

Change in writeable constants

The $WRITEABLECONST compiler switch ( aka $J ) now has a default state of OFF, which will prevent Delphi projects from having writeable constants. Writeable constants refers to the use of a typed constant as a variable modifiable at runtime. Here is an example:

const

foo: Integer = 12;

begin

foo := 14;

end.

In prior releases of Delphi, this was an acceptable construct; constants weren't really constant. With $WRITEABLECONST OFF, this code will now produce a compile error on the assignment to the foo variable in the begin..end block. To fix it, simply change the const declaration to a var declaration.

You may have code that uses a typed const as an initialized local variable with global lifetime, like this:

procedure MyProc;

const

somedata: Integer = 12;

begin

Inc(somedata, 3);

end;

You will need to move the local const out of the procedure and declare it for what it is: a global variable. After making this change, the code segment above becomes:

var

somedata: Integer = 12;

procedure MyProc;

begin

Inc(somedata, 3);

end;

Code that relies heavily on the typed const quirk (such as the ActiveX control wrapper generator) can insert a {$WRITEABLECONST ON} directive in the source file as a quick fix. This practice is forbidden in the RTL, VCL, CLX, and DB source code and discouraged in the IDE sources, but acceptable for fringe units such as ActiveX control wrappers.

In general, you should note that the phrase "writeable constant" is an oxymoron. Prior versions of Delphi allowed them by default to maintain compatibility with an older 16-bit compiler, which is no longer important for most Delphi developers. Use good programming practice; avoid writeable constants.

三. Cardinal类型的负数值

过去,Delphi处理Cardinal类型的负数值时使用32位的机制,这样使得结果为一些零头的值(Cardinal类型允许的最大的值与当前值的差加一)。以下为例子:

var

c: Cardinal;

i: Int64;

begin

c := 4294967294;

i := -c;

WriteLn(i);

end;

在以往版本的Delphi中,I的值应当是2。但是这种情况下这个值明显不对。Delphi 6中,Cardinal类型是先转化为64位的有符号类型,然后取其负数值,所以最终结果I的值为-4294967294。

可能有已经存在的代码依赖于原先错误的Cardinal负数值的实现方法。读者应当对Delphi 的这一新特性引起足够的重视。花足够多的时间来检验你的代码中是否使用了对Cardianl的值的取负数是很值得的,同时确信一点,Delphi的这个新的特性对你的程序的正确性不构成影响。

Unary negation of Cardinal type

In the past, Delphi handled unary negation of Cardinal type numbers using 32 bit operations, which could lead to some odd results. Here is an example of code which uses unary negation:

var

c: Cardinal;

i: Int64;

begin

c := 4294967294;

i := -c;

WriteLn(i);

end;

In previous versions of Delphi, the value of i displayed would be 2. This is obviously incorrect behavior for this case. In Delphi 6, the unary negation is handled after promoting the Cardinal type to a 64 bit signed type, so the final value of i displayed is -4294967294.

It is possible that existing code may rely on the incorrect behavior of unary negation. Delphi users should be aware of this new behavior. It may be worth your time to check your code for instances of unary negation of Cardinal variables, and make sure that your application responds to the new behavior appropriately.

四. 单元DsgnIntf改名及相关变化

工程中对于DsgnIntf的引用,需要更新到一个新的名字:DesignIntf。可能还得加上DesignEditors,VCLEditors 和RTLConsts 到你的引用列表中。并且你还得将designide加入到你的Package的Requires的列表中。对dsnide50的引用可能得改为DesignIde,如果Delphi没有自动更改的话。

任何引用了IDesigner的运行期Package,需要用IdesignerHook来防止运行期时需要designide。运动期代码中,IDesignerHook 足以应付。设计时间的代码也可以使用IDesigner,但是代码要象下例一样:

var

RealDesigner: IDesigner;

...

SomeDesignerHook.QueryInterface(IDesigner,RealDesigner);

...

从IDesignerHook 的一个实例上获得真正的IDesigner接口。IDesignerHook的使用只需要引用Classes和Forms两个单元。IDesigner还需要用DesignIntf,该单元被包含在许多其它Packatge中,而其中的一些可能导致不可再次分发。

Borland在此希望感谢Field的测试员Matt Palcic,感谢他让我们对此引起注意。

DsgnIntf renamed and related changes

References to DsgnIntf in your project should be changed to the new Delphi 6 name, DesignIntf. You may also need to add DesignEditors, VCLEditors and RTLConsts to your uses clause. You will also need to add designide to your package's requires list. References to dsnide50 should probably also be changed to designide if that isn't changed automatically by Delphi.

Any runtime packages that use IDesigner need to use IDesignerHook to avoid a requirement of designide at runtime. In runtime code, IDesignerHook should suffice. Design-time code can use IDesigner, but should use something like

var

RealDesigner: IDesigner;

...

SomeDesignerHook.QueryInterface(IDesigner,RealDesigner);

...

To get the real IDesigner interface from an instance of IDesignerHook. IDesignerHook only requires Classes and Forms to be available. IDesigner requires DesignIntf, which includes many other packages, some of which may not be redistributable.

Borland wishes to thank field tester Matt Palcic for bringing these changes to our attention.

五. 组件编辑器的变化

Delphi 6中,类TComponentEditor有了不同的祖先。在Delphi 5中,它从TInterfacedObject

继承而来;现在它从一个新的类,TbaseComponentEditor继承而来。同时,TComponentEditorClass也变为TbaseComponentEditor的类类型,而不是TComponentEditor的类类型。这些体系结构上的变化可能需要你修改你的老的Delphi的工程。

Component editor changes

The class TComponentEditor has a different ancestry in Delphi 6. In Delphi 5, it descended from TInterfacedObject; it now descends from a new class, TBaseComponentEditor. Also, the class TComponentEditorClass is now a class of TBaseComponentEditor instead of TComponentEditor. These changes in hierarchy may require you to modify your older Delphi projects.

Borland wishes to thank field tester Clive Walden for bringing these changes to our attention.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有