Delphi unicode移植:不兼容的类型:CharToOEM等Win32函数出现'Char'和'AnsiChar'错误?

Jak*_*ays 7 delphi delphi-7 delphi-2010

我正在尝试将一些旧的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;
Run Code Online (Sandbox Code Playgroud)

我得到了"不兼容的类型:'Char'和'AnsiChar'"错误:

找到CharToOEM(外部User32功能)

Windows.pas单位

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

Dav*_*nan 6

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

function CharToOem(Source: PWideChar; Dest: PAnsiChar): BOOL; stdcall;
Run Code Online (Sandbox Code Playgroud)

因此,您需要提供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;
Run Code Online (Sandbox Code Playgroud)

另一种方法是在适当的位置转换为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;
Run Code Online (Sandbox Code Playgroud)

我必须发表评论,我很惊讶地看到OEM字符集在现代仍在积极使用.我以为它已经走了恐龙之路!

  • 如果你在原地修改字符串,不要忘记先调用`UniqueString`. (3认同)