【问题标题】:Delphi unicode porting : Incompatible types: 'Char' and 'AnsiChar' error with Win32 functions like CharToOEM?Delphi unicode 移植:不兼容的类型:'Char' 和 'AnsiChar' 与 CharToOEM 等 Win32 函数的错误?
【发布时间】:2012-03-30 04:27:03
【问题描述】:

我正在尝试将一些旧的 Delphi 7 代码转换为 Delphi 2010

function AnsiToDOS(S: String): String;
begin
  SetLength(Result, Length(S));
  if S <> '' then begin
     CharToOEM(PChar(S), PChar(Result));
  end;
end;

我在该行收到“不兼容的类型:'Char' 和 'AnsiChar'”错误:

CharToOEM(外部 User32 函数)在

中找到

Windows.pas 单位

我能否以某种方式重写此 AnsiToDos 函数,还是需要编写自己的 CharToOEM 例程?

【问题讨论】:

  • 函数CharToOEMBanned 用于微软而不是使用WideCharToMultiByte
  • @RRUZ 很多被禁用的功能是完全合理使用的。
  • @DavidHeffernan 我更喜欢遵循 ​​MSDN 的建议(如果可能的话)。
  • @RRUZ 我原则上同意,但这些特别的建议值得商榷,并且有大量的反对意见。
  • @RRUZ,看注释:“经典的C运行时,“n”个函数被禁止,因为它们很难正确调用。作者在调用这些函数时看到了很多错误” 。我想说的是经典的“枪杀人”。

标签: delphi delphi-7 delphi-2010


【解决方案1】:

在 Unicode Delphi 中,CharToOem 映射到具有以下签名的 Unicode 版本 CharToOemW

function CharToOem(Source: PWideChar; Dest: PAnsiChar): BOOL; stdcall;

因此,您需要提供 ANSI 输出缓冲区,但您的代码提供了 Unicode 输出缓冲区。

自然转换是切换到AnsiString 返回值。同时将函数重命名为StringToOem,以更好地体现其作用。

function StringToOem(const S: String): AnsiString;
begin
  SetLength(Result, Length(S));
  if S <> '' then begin
    CharToOem(PChar(S), PAnsiChar(Result));
  end;
end;

另一种方法是就地转换为 OEM,但为此您需要传入一个 ANSI 字符串并显式调用 API 调用的 ANSI 版本。

function AnsiStringToOem(const S: AnsiString): AnsiString;
begin
  Result := S;
  UniqueString(Result);
  if S <> '' then begin
    CharToOemA(PAnsiChar(Result), PAnsiChar(Result));
  end;
end;

我不得不说,看到 OEM 字符集在现代仍被积极使用,我感到很惊讶。我以为它已经走上了恐龙的道路!

【讨论】:

  • 如果您正在就地修改字符串,请不要忘记先致电UniqueString
  • 从什么时候开始游戏机变成了恐龙?
  • @user539484 从什么时候开始控制台限制为 OEM 文本?
  • 从 Windows NT 开始他们没有。然而,即使是 Microsoft 库存工具也在(tada!)CP_OEMCP 中打印消息。我猜你甚至没有使用 Latin-1 集之外的任何字符?
  • 确实令人惊讶:我刚刚发现 Delphi XE2 中的 WSDLImp.dpr 仍然使用它来将 string 转换为 OEM:` CharToOEMA(PAnsiChar(AStr), PAnsiChar(AStr));`跨度>
【解决方案2】:

最简单的将是(在 C++Builder 中):

typedef AnsiStringT<850> OEMString;
AnsiString (or String) aStr = L"my ansi text";
OEMString oStr = aStr;  // convert
cout << oStr.c_str() << endl;

【讨论】:

    猜你喜欢
    • 2011-10-13
    • 1970-01-01
    • 1970-01-01
    • 2012-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-16
    • 2016-05-19
    相关资源
    最近更新 更多