2012-03-13 4 views
6

Мне нужно вернуть строковое значение сценарию вызова inno. Проблема в том, что я не могу найти способ управлять выделенной памятью. Если я выделяю на стороне DLL, мне нечего снимать со стороны скрипта. Я не могу использовать выходной параметр, потому что в скрипте Pascal нет функции распределения. Что мне делать?Как вернуть строку из DLL в Inno Setup?

ответ

7

Вот пример кода, как выделить строку, которая возвращает из 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

это ответ на ваш вопрос? – kobik

+0

Да, извините, я был вдали от работы на несколько дней (и на выходные). Принято и спасибо. –

2

Единственный практический способ сделать это - выделить строку в настройке Inno и передать указатель на нее вместе с длиной в DLL, которая затем записывает ее до значения длины перед возвратом.

Вот пример кода 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; 

См. Также this thread для более подробной информации.

+0

Как передать его в настройках Inno? –

+0

SetLength (StrVar, SomeLength); –

+0

Ответ был обновлен на примере. – Deanna

2

очень простое решение для случая, когда функция DLL вызывается только один раз в установке - используйте глобальный буфер в вашей dll для строки.

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

сторона Inno-Setup:

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

Мне нравится этот простой ответ, это полезно, когда вы пишете DLL расширения, особенно для Inno Setup. В этом случае вы можете игнорировать недостающую поддержку безопасности повторного входа, которая исходит из глобального буфера. – blerontin

Смежные вопросы