Проблемы Unicode с Delphi 2009 / 2010 и вызовами Windows API

Привет, я использовал эту функцию в Delphi 2006, но теперь с D2010 выдает ошибку. Я думаю, что это связано с переходом на Unicode.

  Function TWinUtils.GetTempFile(Const Extension: STRING): STRING;
  Var
     Buffer: ARRAY [0 .. MAX_PATH] OF char;
  Begin
    Repeat
      GetTempPath(SizeOf(Buffer) - 1, Buffer);
      GetTempFileName(Buffer, '~~', 0, Buffer);
      Result := ChangeFileExt(Buffer, Extension);
    Until not FileExists(Result);
  End;

Что я должен сделать, чтобы это работало?

РЕДАКТИРОВАТЬ

Я получаю "нарушение прав доступа", когда вызывается ChangeFileExt

4 ответа

Решение

Windows.pas

function GetTempFileName(lpPathName, lpPrefixString: PWideChar;
  uUnique: UINT; lpTempFileName: PWideChar): UINT; stdcall;

function GetTempPath(nBufferLength: DWORD; lpBuffer: PWideChar): DWORD; stdcall;

SysUtils.Pas

function ChangeFileExt(const FileName, Extension: string): string;

Попробуй это

  Function TWinUtils.GetTempFile(Const Extension: STRING): STRING;
  Var
     Buffer: ARRAY [0 .. MAX_PATH] OF WideChar;
  Begin
    Repeat
      GetTempPath(Length(Buffer), Buffer);
      GetTempFileName(Buffer, '~~', 0, Buffer);
      Result := ChangeFileExt(Buffer, Extension);
    Until not FileExists(Result);
  End;

или это

  Function GetTempFile(Const Extension: String): String;
  Var
     Buffer: String;
  Begin
      SetLength(Buffer,MAX_PATH);
    Repeat
      GetTempPath( MAX_PATH, PChar( Buffer) );
      GetTempFileName(PChar( Buffer), '~~', 0, PChar( Buffer));
      Result := ChangeFileExt(Buffer, Extension);
    Until not FileExists(Result);
  End;

Для Delphi, Char и PChar типы являются типами WideChar и PWideChar, соответственно.

Если вы используете какой-либо API-интерфейс Windows, который возвращает данные в буферы символов, эти буферы необходимо повторно объявить как массивы байтов или массив AnsiChar.

Если вы вызываете эти API-интерфейсы Windows и отправляете в буферы, если вы использовали функцию sizeof, сообщая API, как долго ваш буфер. Эти вызовы должны быть изменены на функцию Length, поскольку для API-интерфейса widechar Windows требуется количество символов, а не количество байтов.

До свидания.

Использование GetTempPathA а также GetTempFileNameAАнси версии GetTempPath а также GetTempFileName, Они по-прежнему доступны в Delphi 2009 и упоминаются в файле справки Delphi 2009, но не рекламируются.

В Delphi 2009 Char является символом Unicode. Функция, вероятно, требует массив AnsiChar.

Только что проверил. И GetTempFilename, и GetTempPath требуют PWideString.

Что такое сообщение об ошибке?

Я бы рекомендовал всегда, и я действительно имею в виду всегда, просматривать документы о точных ожиданиях каждой функции API в отношении параметра dwSize и / или возвращаемого значения.

К сожалению, есть много разных случаев, поэтому просто сказать "все строковые функции требуют / возвращают число символов" не совсем правильно и может привести читателя к кошмару спорадических неверных AV указателей.

  • Большинство функций API ожидают / возвращают количество символов, но некоторые этого не делают.
  • Некоторые считают завершающий нулевой символ, а некоторые нет.
  • Некоторые функции ведут себя по-разному, когда передается нулевой указатель, и когда передается ненулевой указатель.
  • И есть также некоторые функции, которые вообще не предлагают никакого способа указать необходимый размер буфера.

Все эти вещи можно легко найти в документации, но это нужно прочитать. В самом деле. Это может сэкономить вам часы.

Другие вопросы по тегам