新的字符串类型如何在Delphi 2009/2010中工作?

时间:2009-09-09 12:27:45

标签: delphi unicode string delphi-2009

我必须将大型遗留应用程序转换为Delphi 2009,它使用字符串,AnsiStrings,WideStrings和UTF8数据,我很难理解新字符串类型的工作方式以及如何使用它们。 / p>

应用程序完全支持使用TntUnicodeControls的Unicode,并且第三方DLL需要特定编码的字符串,主要是UTF8和UTF16,这使得转换任务不像人们所怀疑的那样微不足道。

我特别遇到C DLL调用和选择正确类型的问题。 我还得到了许多隐式字符串转换的印象,因为无论Delphi字符串是如何编码的,其中一个DLL似乎总是接收UTF-8编码的字符串。

有人可以提供关于新的Delphi 2009字符串类型UnicodeString和RawByteString的简短概述,可能是转换2009年前应用程序时的一些用法提示和可能的陷阱吗?

5 个答案:

答案 0 :(得分:11)

请参阅Delphi and Unicode,这是MarcoCantù撰写的白皮书,我猜 The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!),由乔尔撰写。

一个缺陷是默认的Win32 API调用已被映射为使用W(宽字符串)版本而不是A(ANSI)版本,例如ShellExecuteA如果您的代码执行棘手的指针代码假设内部AnsiString的布局,它会破裂。后退是将PChar替换为PAnsiChar,将Char替换为AnsiChar,将string替换为AnsiString,并在Win32 API的末尾追加A.要求那部分代码。代码实际编译并正常运行后,您可以重构代码以使用stringUnicodeString)。

答案 1 :(得分:8)

本周五观看关于“在程序中使用Unicode和其他编码”的CodeRage 4话题,或者等到它的重播在线提供。

我将介绍一些编码并解释字符串格式。

幻灯片很快就会上线(我今天会尝试将它们放到网上)并且包含很多你应该在互联网上阅读的内容的参考资料(但我必须承认我忘记了eed3si9n发布的关于Unicode的Joel的链接)。

今天将使用上传和链接编辑此答案。


编辑:

如果您有一个小样本,您可以在其中显示您的C / C ++ DLL接收UTF8编码的字符串,但认为它们应该以其他方式编码,请发布它(邮寄给我;几乎任何东西at the pluimers dot com都给我,特别是如果你在at符号前使用我的名字。)

会话材料现在可以是downloaded,包括“在程序中使用Unicode和其他编码”会话。

这些是该会话的链接:

阅读以下内容:

  1. Marco Cantu,白皮书“Delphi and Unicode
  2. Marco Cantu,演讲“Delphi and Unicode
  3. Nick Hodges,白皮书“Delphi in a Unicode World
  4. 相关的在线帮助主题:

    1. What's New in Delphi and C++Builder 2009
    2. 字符串类型:Base: ShortString, AnsiString, WideString, UnicodeString
    3. 字符串类型:Unicode (including internal memory layouts of the string types)
    4. 字符串类型:Enabling for Unicode
    5. 字符串类型:RawByteString (AnsiString with CodePage $ffff)
    6. 字符串类型:UTF8String (AnsiString with CodePage 65001)
    7. String< - > PChar转换:PChar fundamentals
    8. String< - > PChar转换:Returning a PChar Local Variable
    9. String< - > PChar转换:Passing a Local Variable as a PChar
    10. 希望这能让你前进。如果没有,请给我发邮件,我会尽力扩大答案。

答案 2 :(得分:0)

请注意,它不仅会出现真正的字符串代码。它还会遇到代码,其中PCHAR用于遍历缓冲区或与API接口。

E.g。动态加载DLL的头文件初始化代码(getprocedureaddress / loadlibray)

答案 3 :(得分:0)

似乎我的几乎所有问题都来自于UTF8String的分配自动转换。

我已经使用UTF8String使用了旧代码,只是为了帮助我思考变量应该包含哪种类型的字符串。

在开始移植我的应用程序时,出于同样的原因,我将AnsiString替换为UTF8String,但代码依赖于UTF8String只是(经典){{1}的别名}

现在通过自动转换,假设不再成立,这造成了许多问题。

从2009年以前的Delphi代码移植时使用AnsiString时要小心!

答案 4 :(得分:0)

在使用不同版本的Delphi或C ++ Builder构建的dll之间传递字符串时要注意的另一件事是,从2009年开始,AnsiStringBase的StrRec部分获得了两个额外的字段; codePage和elemSize。它们各为2个字节(短整数),因此StrRec的大小现在是12个字节而不是8个。这可能导致内存分配和破坏的无效指针异常问题,即使字符串的数据部分似乎传输正常。 / p>