Problemi Unicode con Delphi 2009/2010 e chiamate API Windows
-
07-07-2019 - |
Domanda
Ciao, ho usato questa funzione in Delphi 2006, ma ora con D2010 genera un errore. Penso che sia legato al passaggio a 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;
Cosa devo fare per farlo funzionare?
Modifica
Ottengo una "violazione di accesso" quando viene chiamato ChangeFileExt
Soluzione
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;
Prova questo
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;
o questo
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;
Per i tipi Delphi, Char e PChar sono rispettivamente i tipi WideChar e PWideChar.
Se si utilizzano API di Windows che restituiscono dati in buffer di caratteri, tali buffer devono essere dichiarati nuovamente come array di byte o come array di AnsiChar.
Se stai chiamando queste API di Windows e invii buffer, se hai utilizzato la funzione sizeof quando hai detto all'API quanto è lungo il tuo buffer. Queste chiamate devono essere modificate nella funzione Lunghezza, in quanto le API widechar di Windows richiedono il numero di caratteri, non il numero di byte .
Ciao.
Altri suggerimenti
Con Delphi 2009, Char è un carattere Unicode. La funzione probabilmente richiede un array di AnsiChar.
L'ho appena controllato. Sia GetTempFilename che GetTempPath richiedono PWideString.
Qual è il messaggio di errore?
Consiglierei sempre, e intendo davvero sempre, di dare un'occhiata ai documenti sulle aspettative esatte di ciascuna funzione API riguardo al parametro dwSize e / o al valore restituito.
Sfortunatamente ci sono molti casi diversi, quindi basta dire " tutte le funzioni di stringa hanno bisogno / restituiscono il numero di caratteri " non è del tutto corretto e può mandare il lettore in un incubo di sporadici AV puntatori non validi.
- La maggior parte delle funzioni API prevede / restituisce il numero di caratteri, ma alcuni non lo fanno.
- Alcuni contano il carattere null terminante, altri no.
- Alcune funzioni si comportano diversamente quando viene passato un puntatore zero rispetto a quando a puntatore diverso da zero.
- E ci sono anche alcune funzioni che non offrono alcun modo per indicare la dimensione del buffer richiesta.
Tutte queste cose possono essere trovate facilmente nei documenti, ma si dovrebbe leggere. Veramente. Può farti risparmiare ore.
Usa GetTempPathA
e GetTempFileNameA
, le versioni Ansi di GetTempPath
e GetTempFileName
. Sono ancora disponibili in Delphi 2009 e menzionati nel file della guida di Delphi 2009, ma non pubblicizzati.