【问题标题】:how to use MultiByteToWideChar in delphi?如何在delphi中使用MultiByteToWideChar?
【发布时间】:2017-07-16 09:02:34
【问题描述】:

我正在尝试使用 MultiByteToWideChar,但我得到了 'undeclared identifier' 。它在哪里声明?哪个“使用”?

我正在使用 Embarcadero Delphi XE8。

【问题讨论】:

标签: string delphi unicode delphi-xe8


【解决方案1】:

MultiByteToWideChar Windows API函数(Win32/Win64)在Delphi或FreePascal中定义在Windows单元;只需将WindowsWinapi.Windows 添加到uses 子句即可。

您可能希望使用 Delphi 编写的包装函数将 RawByteString(或 AnsiString)转换为 UnicodeString,反之亦然,而不是直接调用 MultiByteToWideChar。由于底层缓冲区的长度计算不正确,直接调用可能容易出错。

请注意,Delphi RawByteString 或 AnsiString 具有存储 Windows 代码页值的属性,它由下面代码中的 SetCodePage() 调用设置。代码使用显式类型,PAnsiChar vs PWideChar 和 RawByteString vs UnicodeString 以避免歧义。

uses
  Windows;

const
  CP_UNICODE_LE = 1200;

function StringToWideStringCP(const S: RawByteString; CP: Integer): UnicodeString;
var
  P: PAnsiChar;
  pw: PWideChar;
  I, J: Integer;
begin
  Result := '';
  if S = '' then
    Exit;
  if CP = CP_UTF8 then
  begin
    // UTF8
    Result := UTF8ToUnicodeString(S);
    Exit;
  end;
  P := @S[1];
  I := MultiByteToWideChar(CP, 0, P, Length(S), nil, 0);
  if I <= 0 then
    Exit;
  SetLength(Result, I);
  pw := @Result[1];
  J := MultiByteToWideChar(CP, 0, P, Length(S), pw, I);
  if I <> J then
    SetLength(Result, Min(I, J));
end;


function WideStringToStringCP(const w: UnicodeString; CP: Integer)
  : RawByteString;
var
  P: PWideChar;
  I, J: Integer;
begin
  Result := '';
  if w = '' then
    Exit;
  case CP of
    CP_UTF8:
      begin
        // UTF8
        Result := UTF8Encode(w);
        Exit;
      end;
    CP_UNICODE_LE:
      begin
        // Unicode codepage
        CP := CP_ACP;
      end;
  end;

  P := @w[1];
  I := WideCharToMultibyte(CP, 0, P, Length(w), nil, 0, nil, nil);
  if I <= 0 then
    Exit;
  SetLength(Result, I);
  J := WideCharToMultibyte(CP, 0, P, Length(w), @Result[1], I, nil, nil);
  if I <> J then
    SetLength(Result, Min(I, J));
  SetCodePage(Result, CP, False);
end;

【讨论】:

  • 未声明的标识符:'CP_UNICODE_LE'
【解决方案2】:

它是一个Windows API函数,所以如果你想调用它,你必须使用Winapi.Windows

如果您编写跨平台代码,请改为调用UnicodeFromLocaleChars

【讨论】:

  • 但请注意,在 POSIX 平台(macOS、iOS,也可能是 Android)上,UnicodeFromLocaleChars 是 ssslllooowww。在我的Mobile.AnsiString 单元中(在移动编译器中没有 AnsiString 时编写),我可以将其加速 10 倍甚至更多。在 Windows 上,它很快,但并不完全正确(MultiByteToWideChar 也不正确,它在内部使用)。
猜你喜欢
  • 2011-10-05
  • 1970-01-01
  • 2016-05-12
  • 2013-08-22
  • 2021-10-25
  • 2014-08-24
  • 2011-05-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多