【问题标题】:Does SetString have two version for AnsiString and UnicodeString accordingly?SetString 是否有相应的 AnsiString 和 UnicodeString 两个版本?
【发布时间】:2019-10-27 10:00:49
【问题描述】:

我正在使用 Delphi XE3。我只是想知道 Delphi 字符串函数,比如 Windows SDK,是否有两个版本,一个用于 AnsiString,一个用于 UnicodeString?

例如,SetString 过程:

procedure SetString(var S: String; Buffer: PChar; Length: Integer);

是否有两个版本,一个是:

procedure SetString(var S: AnsiString; Buffer: PAnsiChar; Length: Integer);

另一个版本是:

procedure SetString(var S: UnicodeString; Buffer: PUnicodeChar; Length: Integer);

我在Delphi源码中搜索过,但在system.pas中只找到如下函数:

procedure _SetString(s: _PShortStr; buffer: _PAnsiChr; len: Byte);

好像System.pas只定义了Ansi字符串版本?

【问题讨论】:

  • 我认为你问错了问题。您的意思是询问 AnsiString 和 UnicodeString。 WideString 是 COM BSTR 类型的 Delphi 包装器。我希望你没有使用 WideString,除非你在做 COM 互操作。
  • @DavidHeffernan,你是对的。我的意思是 UnicodeString,我把它和 C++ 的 Widechar 混淆了。
  • C++ 没有宽字符类型。 C++ 中的字符类型有 char 和 wchar_t。

标签: string delphi


【解决方案1】:

是的,Delphi 有这个函数的不同版本来处理不同类型的字符串和字符(以及它们的组合,即有两个以上的版本)。

如果您编写这个简单的测试并查看汇编代码,您将看到实际发生的情况:

procedure DoTest;
var
  s1: AnsiString;
  s2: WideString;
begin
  SetString(s1, PAnsiChar('Test1'), 3);
  SetString(s2, PWideChar('Test1'), 3);
end;

在这个函数的最后设置一个断点并打开反汇编窗口(Ctrl+Alt+D):

Project1.dpr.15: SetString(s1, PAnsiChar('Test1'), 3);
0041BD71 6A00             push $00
0041BD73 BAC0BD4100       mov edx,$0041bdc0
0041BD78 8D45FC           lea eax,[ebp-$04]
0041BD7B B903000000       mov ecx,$00000003
0041BD80 E817B7FEFF       call @LStrFromPCharLen        ; <-- called AnsiString version
Project1.dpr.16: SetString(s2, PWideChar('Test1'), 3);
0041BD85 BAC8BD4100       mov edx,$0041bdc8
0041BD8A 8D45F8           lea eax,[ebp-$08]
0041BD8D B903000000       mov ecx,$00000003
0041BD92 E8E1B6FEFF       call @WStrFromPWCharLen       ; <-- called WideString version

【讨论】:

    【解决方案2】:

    事实上,SetString 有四种不同的版本,每个版本对应一种不同的字符串类型。这些字符串类型是:

    • ShortString
    • AnsiString
    • UnicodeString
    • WideString

    虽然您询问了WideString,但我怀疑您实际上是想询问UnicodeString。在 Delphi 2009 及更高版本上,stringUnicodeString 的别名。 WideString 类型是 COM BSTR 类型的 Delphi 包装器。您只能将它用于 COM 互操作,以及在 Dephi 2007 及更早版本上支持 Unicode。

    【讨论】:

    • 其实有8个不同的版本,因为第二个参数可以是PAnsiChar或者PWideChar
    • 第一个参数和第二个参数必须匹配吗?根据zed的评论,似乎不需要匹配。所以我可以直接用 PAnsiChar 构造一个 Unicode 字符串,像这样:SetString(var S: UnicodeString; Buffer: PAnsiChar; Length: Integer)?
    • 这是否也适用于所有其他与字符串相关的函数,例如 Concat?在一些字符串相关的函数中,比如Pos,我可以看到它的文档清楚的说不同的字符串类型有不同的版本。但是,对于其他的,例如 SetString 和 Concat,我在帮助文档中看不到此类信息。遇到这种情况,是不是要自己搜索源码或者调试成反汇编代码才知道有多少个版本?
    • 为什么需要知道有多少个版本?你不能仅仅依靠正确实施的 RTL 吗?
    • @alancc 在编译器默默地完成它的工作之前,不要担心字符串函数。只有当您看到有关 ExplicitImplicit 字符串转换的警告时,您才需要注意这一点。
    猜你喜欢
    • 2015-01-09
    • 2014-01-19
    • 1970-01-01
    • 2017-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多