从托管输出到Inno Setup的脚本C#DLL返回一个字符串从托管输出到Inno Setup的脚本

2019-05-12 09:27发布

我一直在使用它公开了一个功能的C#DLL 托管输出是直接由Inno Setup的帕斯卡尔脚本调用。 此功能需要返回一个字符串,Inno Setup的。 我的问题是如何才能做到这一点?
我的优选的方法是从创新安装的缓冲器传递给C#函数将返回此缓冲区内的字符串。 我想出了这样的代码:

C#功能:

[DllExport("Test", CallingConvention = CallingConvention.StdCall)]
static int Test([Out, MarshalAs(UnmanagedType.LPWStr)] out string strout)
{
   strout = "teststr";
   return strout.Length;
}

Inno Setup的脚本:

function Test(var res: String):Integer; external 'Test@files:testdll.dll stdcall';

procedure test1; 
var
    Res: String;
    l: Integer;
begin
    SetLength(Res,256);
    l := Test(Res);
    { Uncommenting the following line causes an exception }
    { SetLength(Res,l); }
    Log('"Res"');
end;

当我运行这段代码的Res变量是空的(我看“”在日志中)

我怎样才能返回从这个DLL的字符串?

请注意,我用的Inno Setup的Unicode版本。 我也不想使用COM调用此函数,也没有在DLL分配一个缓冲区,并返回到Inno Setup的。

Answer 1:

我建议你使用BSTR类型,它曾经是互操作函数调用的数据类型。 在你的C#侧你最好马歇尔的字符串作为UnmanagedType.BStr类型和你使用的Inno Setup的侧WideString ,这与兼容BSTR类型。 所以,你的代码将然后改变这个(另见Marshalling sample的托管输出文档的章节):

[DllExport("Test", CallingConvention = CallingConvention.StdCall)]
static int Test([MarshalAs(UnmanagedType.BStr)] out string strout)
{
    strout = "teststr";
    return 0; // indicates success
}

而就在使用的Inno Setup的侧WideString这样:

[Code]
function Test(out strout: WideString): Integer;
  external 'Test@files:testdll.dll stdcall';

procedure CallTest;
var
  retval: Integer;
  str: WideString;
begin
  retval := Test(str);
  { test retval for success }
  Log(str);
end;


文章来源: Returning a string from a C# DLL with Unmanaged Exports to Inno Setup script