如何将DLL中的字符串返回到Inno Setup

How to return a string from a DLL to Inno Setup?

本文关键字:返回 Inno Setup 字符串 DLL      更新时间:2023-10-16

我需要向调用Inno Setup脚本返回一个字符串值。问题是我找不到管理分配内存的方法。如果我在DLL端进行分配,那么在脚本端就没有任何要处理的内容。我不能使用输出参数,因为Pascal脚本中也没有分配函数。我该怎么办?

以下是如何分配从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;

一个非常简单的解决方案,适用于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设置端:

function MyFunc: PChar;
external 'MyFunc@files:mydll.dll cdecl';

唯一实用的方法是在Inno Setup中分配一个字符串,并将指向该字符串的指针和长度一起传递给DLL,然后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;

有关更多最新讨论,请参阅此线程。