Delphi unicode porting: несовместимые типы: ошибка "Char" и "AnsiChar" с функциями Win32, такими как CharToOEM?

Я пытаюсь преобразовать старый код 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) найдено в

окна.pas unit

могу ли я как-то переписать эту функцию AnsiToDos или мне нужно написать свою собственную процедуру CharToOEM?

2 ответов


В Юникоде 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 и вызовите версию ANSI вызова API явно.

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

Я должен прокомментировать, что я удивлен тем, что набор символов OEM все еще активно используется в наши дни. Я думал, он пошел по пути динозавров!


самым простым будет (в C++Builder):

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