1

I am using Delphi XE3. I just wonder if Delphi string functions, like Windows SDK, have two versions, one for AnsiString and one for UnicodeString?

For example, SetString procedure:

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

Does it have two versions, one is:

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

and another version is:

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

I have searched in Delphi source code, but only found the following function in system.pas:

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

It seems that System.pas only define the Ansi string version?

alancc
  • 487
  • 2
  • 24
  • 68
  • I think you asked the wrong question. You meant to ask about AnsiString and UnicodeString. WideString is the Delphi wrapper for the COM BSTR type. You aren't using WideString I hope, unless you are doing COM interop. – David Heffernan Oct 27 '19 at 12:04
  • @DavidHeffernan, you are correct. I mean UnicodeString, I confused this with C++'s widechar. – alancc Oct 27 '19 at 22:54
  • C++ does not have a wide char type. The character types in C++ are char and wchar_t. – David Heffernan Oct 28 '19 at 06:59

2 Answers2

2

Yes, Delphi has different versions of this function to work with different types of strings and chars (and their combinations, i.e. there are more than two versions).

If you write this simple test and look at the assembler code, you will see what is actually happen:

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

Set a break-point at the end of this function and open Disassembly window (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
dummzeuch
  • 10,975
  • 4
  • 51
  • 158
zed
  • 798
  • 7
  • 12
2

In fact there are four different versions of SetString, one for each different string type. Those string types are:

  • ShortString
  • AnsiString
  • UnicodeString
  • WideString

Although you asked about WideString, I suspect that you actually meant to ask about UnicodeString. On Delphi 2009 and later, string is an alias to UnicodeString. The WideString type is the Delphi wrapper for the COM BSTR type. You only use it for COM interop, and for Unicode support on Dephi 2007 and earlier.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Actually, there are 8 different versions, since second parameter can be `PAnsiChar` or `PWideChar`. – zed Oct 27 '19 at 12:49
  • Does the first and second parameter must match? Based on zed's comment, it seems it does not need to match. So I can use PAnsiChar to construct a Unicode string directly, like this: SetString(var S: UnicodeString; Buffer: PAnsiChar; Length: Integer)? – alancc Oct 27 '19 at 22:56
  • Does this also apply to all other string related functions, such as Concat? In some of the string related functions, such as Pos, I can see its document clearly said there are different versions for different string types. However, for others, such as SetString and Concat, I cannot see such info in the help document. In such a case, must I search the source codes or debug into disassembled codes to know how many versions they have? – alancc Oct 27 '19 at 23:02
  • Why do you need to know how many versions there are? Can't you just rely on the RTL being implemented correctly? – David Heffernan Oct 28 '19 at 05:51
  • @alancc Don't worry about string functions until compiler do its job silently. You need to pay attentions to this only when you'll see warnings about [**Explicit**](http://docwiki.embarcadero.com/RADStudio/Rio/en/W1060_Explicit_string_cast_with_potential_data_loss_from_%27%25s%27_to_%27%25s%27_(Delphi)) or [**Implicit**](http://docwiki.embarcadero.com/RADStudio/Rio/en/W1057_Implicit_string_cast_from_%27%25s%27_to_%27%25s%27_(Delphi)) string cast. – zed Oct 28 '19 at 05:59