Devo restituire un valore stringa allo script di chiamata inno setup. Il problema è che non riesco a trovare un modo per gestire la memoria allocata. Se alloco sul lato DLL, non ho nulla da deallocare sul lato script. Non riesco a utilizzare un parametro di output, perché non esiste alcuna funzione di allocazione in Pascal Script. Cosa dovrei fare?Come restituire una stringa da una DLL a Inno Setup?
risposta
Ecco un codice di esempio di come allocare una stringa che ritorna da una DLL:
[code]
Function GetClassNameA(hWnd: Integer; lpClassName: PChar; nMaxCount: Integer): Integer;
External '[email protected] StdCall';
function GetClassName(hWnd: Integer): string;
var
ClassName: String;
Ret: Integer;
begin
// allocate enough memory (pascal script will deallocate the string)
SetLength(ClassName, 256);
// the DLL returns the number of characters copied to the buffer
Ret := GetClassNameA(hWnd, PChar(ClassName), 256);
// adjust new size
Result := Copy(ClassName, 1 , Ret);
end;
L'unico modo pratico per eseguire questa operazione consiste nell'assegnare una stringa in Inno Setup e passare un puntatore a quello insieme alla lunghezza della DLL che quindi scrive fino al valore della lunghezza prima di tornare.
Ecco alcuni esempi di codice taken from the newsgroup.
function GetWindowsDirectoryA(Buffer: AnsiString; Size: Cardinal): Cardinal;
external '[email protected] stdcall';
function GetWindowsDirectoryW(Buffer: String; Size: Cardinal): Cardinal;
external '[email protected] stdcall';
function NextButtonClick(CurPage: Integer): Boolean;
var
BufferA: AnsiString;
BufferW: String;
begin
SetLength(BufferA, 256);
SetLength(BufferA, GetWindowsDirectoryA(BufferA, 256));
MsgBox(BufferA, mbInformation, mb_Ok);
SetLength(BufferW, 256);
SetLength(BufferW, GetWindowsDirectoryW(BufferW, 256));
MsgBox(BufferW, mbInformation, mb_Ok);
end;
vedono anche this thread per più aggiornate discussione.
Come posso assegnarlo a Inno Setup? –
SetLength (StrVar, SomeLength); –
La risposta è stata aggiornata con un esempio. – Deanna
una soluzione molto semplice per il caso in cui la funzione di DLL viene chiamato una sola volta nell'installazione - utilizzare un buffer globale nella DLL per la stringa.
lato DLL:
char g_myFuncResult[256];
extern "C" __declspec(dllexport) const char* MyFunc()
{
doSomeStuff(g_myFuncResult); // This part varies depending on myFunc's purpose
return g_myFuncResult;
}
lato Inno-Setup:
function MyFunc: PChar;
external '[email protected]:mydll.dll cdecl';
Mi piace questa semplice risposta, è utile quando si scrive una DLL di estensione soprattutto per Inno Setup. In questo caso è possibile ignorare il supporto mancante per la sicurezza di rientro che deriva dall'utilizzo di un buffer globale. – blerontin
risponde a questa domanda? – kobik
Sì, scusate, ero fuori dal lavoro per alcuni giorni (e il fine settimana). Accettato e grazie. –