繁体   English   中英

使用分配的字符缓冲区调用 DLL function function 在 Inno Setup 中填充

[英]Calling a DLL function with an allocated character buffer that the function fills in Inno Setup

我在 Windows 10 64 位上使用(Unicode)Inno Setup 6.0.5。

我要使用的导出符号具有签名:

typedef int(__stdcall *GetDirVST2x86) (LPWSTR lpString1);

Inno Setup [Code]部分的声明如下:

function GetDirVST2x86(var lpString1: String): Integer;
external 'GetDirVST2x86@files:R2RINNO.DLL stdcall setuponly';

其中, lpString1将包含指向 function 返回后的宽字符串的指针,并且 R2RINNO.DLL 是 32 位 DLL。

现在我的问题是,如果我编译并运行这个设置,当我尝试检索值时就会发生读取访问冲突。 当我从 C 程序执行相同的 function 时,我得到了正确的结果 从 Inno 脚本中的原型声明中删除var会获取一个空(或可能)空或空字符串,因此这也无济于事。

我没有想要使用的 DLL 的源代码,我从 IDA 找到了签名。 脚本引擎 Inno Setup 似乎完全不够用,因为它根本不支持指针。

我观察到的一件有趣的事情是,如果我将lpString1的类型更改为CardinalInteger并使用IntToStr获取字符串,我将获得创建设置的目录的值。

这是一个有效的 C 代码:

#include <windows.h>
#include <stdio.h>

#define _UNICODE
#define UNICODE

typedef int(WINAPI *GetDirVST2x86) (LPWSTR );

int main() {
    HMODULE hModule = LoadLibrary("R2RINNO.DLL");
    if (NULL != hModule) {
        GetDirVST2x86 pGetDirVST2x86 = (GetDirVST2x86) GetProcAddress (hModule, "GetDirVST2x86");
        if (NULL != pGetDirVST2x86) {
            LPWSTR lpszVST2x86;
            pGetDirVST2x86(lpszVST2x86);
            wprintf(lpszVST2x86);
        }
        FreeLibrary(hModule);
    }
}

这是 output:

C:\Program Files (x86)\Steinberg\VstPlugins

这是我想使用的 function 的 IDA 屏幕截图: GetDirVST2x86 IDA 反汇编

等效于 C 声明的 Pascal 脚本应为:

function GetDirVST2x86(lpString1: string): Integer;
  external 'GetDirVST2x86@files:R2RINNO.DLL stdcall setuponly';

(即没有var ,因为它是输入字符指针参数)。

假设 function 合约是您(作为调用者)分配一个缓冲区并将其提供给 function 来填写,您应该像这样调用 ZC1C425268E68385D1AB5074C17A9:

var
  Buf: string;
begin
  { Allocate buffer for the result large enough according to the API specification }
  SetLength(Buf, 1000);
  GetDirVST2x86(Buf);
  SetLength(Result, Pos(#0, Result) - 1);
end;

另请参阅如何将字符串从 DLL 返回到 Inno Setup?

暂无
暂无

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

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