2012-03-13 18 views
6

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

7

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; 
+0

risponde a questa domanda? – kobik

+0

Sì, scusate, ero fuori dal lavoro per alcuni giorni (e il fine settimana). Accettato e grazie. –

2

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.

+0

Come posso assegnarlo a Inno Setup? –

+0

SetLength (StrVar, SomeLength); –

+0

La risposta è stata aggiornata con un esempio. – Deanna

2

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'; 
+1

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

Problemi correlati