2012-03-13 11 views
6

Necesito devolver un valor de cadena a la secuencia de comandos inno setup. El problema es que no puedo encontrar una forma de administrar la memoria asignada. Si asigno en el lado de la DLL, no tengo que desasignar nada en el lado del script. No puedo usar un parámetro de salida porque tampoco hay una función de asignación en Pascal Script. ¿Que debería hacer?¿Cómo devolver una cadena de un archivo DLL a Inno Setup?

Respuesta

7

Aquí hay un código de ejemplo de cómo asignar una cadena que regresa de 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

hace esta pregunta usted pregunta? – kobik

+0

Sí, lo siento, estuve fuera del trabajo por unos días (y el fin de semana). Aceptado y gracias. –

2

La única forma práctica de hacerlo es asignar una cadena en la configuración de Inno, y pasar un puntero a eso junto con la longitud de su DLL que luego escribe hasta el valor de longitud antes de volver.

Aquí hay un código de ejemplo 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; 

Véase también this thread de más hasta la fecha discusión.

+0

¿Cómo se asignan en Inno Setup? –

+0

SetLength (StrVar, SomeLength); –

+0

La respuesta se ha actualizado con un ejemplo. – Deanna

2

Una solución muy simple para el caso en que la función DLL se llama una sola vez en la instalación - usa un buffer global en tu dll para la cadena.

lado 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; 
} 

lado Inno-Setup:

function MyFunc: PChar; 
external '[email protected]:mydll.dll cdecl'; 
+1

Me encanta esta simple respuesta, es útil cuando escribe una extensión DLL especialmente para Inno Setup. En este caso, puede ignorar el soporte faltante para la seguridad de reingreso que proviene del uso de un buffer global. – blerontin

Cuestiones relacionadas