Как вернуть строку из DLL в Inno Setup? - PullRequest
6 голосов
/ 13 марта 2012

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

Ответы [ 3 ]

7 голосов
/ 13 марта 2012

Вот пример кода, как выделить строку, которая возвращается из DLL:

[code]
Function GetClassNameA(hWnd: Integer; lpClassName: PChar; nMaxCount: Integer): Integer; 
External 'GetClassNameA@User32.dll 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;
3 голосов
/ 09 марта 2014

Очень простое решение для случая, когда функция 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 'MyFunc@files:mydll.dll cdecl';
2 голосов
/ 13 марта 2012

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

Вот пример кода , взятого из группы новостей .

function GetWindowsDirectoryA(Buffer: AnsiString; Size: Cardinal): Cardinal;
external 'GetWindowsDirectoryA@kernel32.dll stdcall';
function GetWindowsDirectoryW(Buffer: String; Size: Cardinal): Cardinal;
external 'GetWindowsDirectoryW@kernel32.dll 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;

Также см. эту ветку для более актуального обсуждения.

...