简体   繁体   English

如何将字符串从 DLL 返回到 Inno Setup?

[英]How to return a string from a DLL to Inno Setup?

I need to return a string value to the calling Inno Setup script.我需要向调用 Inno Setup 脚本返回一个字符串值。 Problem is I can't find a way to manage the allocated memory.问题是我找不到管理分配内存的方法。 If I allocate on the DLL side, I don't have anything to deallocate with on the script side.如果我在 DLL 端分配,则在脚本端我没有任何要释放的东西。 I can't use an output parameter, because there is no allocation function in the Pascal Script either.我不能使用输出参数,因为 Pascal 脚本中也没有分配函数。 What should I do?我应该怎么办?

Here is a sample code of how to allocate a string that returns from a DLL:以下是如何分配从 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;

A very simple solution for the case where the DLL function is called only once in the installation - use a global buffer in your dll for the string.对于在安装中仅调用一次 DLL 函数的情况,一个非常简单的解决方案 - 在 dll 中为字符串使用全局缓冲区。

DLL side: 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 side: Inno-Setup 端:

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

The only practical way to do this is to allocate a string in Inno Setup, and pass a pointer to that along with the length to your DLL that then writes to it up to the length value before returning.唯一可行的方法是在 Inno Setup 中分配一个字符串,并将指向该字符串的指针以及长度传递给您的 DLL,然后在返回之前将其写入到长度值。

Here's some example code taken from the newsgroup .这是从新闻组中获取的一些示例代码。

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;

Also see this thread for more up to date discussion.另请参阅此线程以获取更多最新讨论。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM