Проблемы 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 ожидают / возвращают количество символов, но некоторые этого не делают.
- Некоторые считают завершающий нулевой символ, а некоторые нет.
- Некоторые функции ведут себя по-разному, когда передается нулевой указатель, и когда передается ненулевой указатель.
- И есть также некоторые функции, которые вообще не предлагают никакого способа указать необходимый размер буфера.
Все эти вещи можно легко найти в документации, но это нужно прочитать. В самом деле. Это может сэкономить вам часы.