将字符串数组从C#返回到Inno Setup

时间:2016-10-11 06:48:50

标签: c# inno-setup dllexport pascalscript

我正在使用Robert Giesecke的Unmanaged Exports NuGet并在C#中使用以下方法:

[DllExport("DummyMethod", CallingConvention = CallingConvention.StdCall)]
public static void DummyMethod(
    [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] out string[] test, out int count)
{
    count = 3;
    test = new[] {"test1", "test2", "test3"};
}

在Inno Setup中,这是我的代码:

[Code]
procedure DummyMethod(out Test: TArrayOfString; out Count: Integer);
external 'DummyMethod@files:MyDll.dll stdcall';

procedure InitializeWizard();
  var Test : TArrayOfString;
  var Count : Integer;
begin
  DummyMethod(Test, Count);
  MsgBox(Test[0], mbError, MB_OK);
end;

出于某种原因,Count始终为0,Test始终为空。

我看了几个例子,但是找不到Inno Setup从C#DLL中获取字符串数组的例子。

2 个答案:

答案 0 :(得分:2)

带有UnmanagedType.LPArray的{​​{1}}映射到char的指针数组(C风格string)。在Unicode Pascal脚本中char**。 Pascal脚本无法将其神奇地转换为array of PAnsiCharTArrayOfString)。

你可以像这样转换它:

array of string

(使用Unicode Inno安装程序测试)

附注:

  • 目前尚不清楚,谁为type TArrayOfPAnsiChar = array of PAnsiChar; procedure DummyMethod(out StringPtrs: TArrayOfPAnsiChar; out Count: Integer); external 'DummyMethod@files:ArrayInno.dll stdcall'; function DummyMethodWrapper: TArrayOfString; var ArrayOfPAnsiChar: TArrayOfPAnsiChar; I, Count: Integer; begin DummyMethod(ArrayOfPAnsiChar, Count); SetArrayLength(Result, Count); for I := 0 to Count - 1 do begin Result[I] := ArrayOfPAnsiChar[I]; end; end; 和单个字符数组进行内存分配。我充其量只能闻到内存泄漏。
  • 您可能希望使用16位字符缓冲区而不是8位字符缓冲区来允许完整的Unicode。虽然注意到这在Pascal脚本中更难实现,因为它缺少16位字符指针类型。

答案 1 :(得分:2)

可以封送BSTR / WideString数组,该数组应允许完整的Unicode。

在C#中:

[DllExport("ReturnsArrayOfStrings", CallingConvention.StdCall)]
public static void ReturnsArrayOfStrings(
    [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.BStr, SizeParamIndex = 1)] out string[] values,
    out int numValues)
{
    values = new[] { "one", "two", "three" };
    numValues = values.Length;
}

在Inno设置中:

type
  TArrayOfWideString = array of WideString;

procedure ReturnsArrayOfStrings(out values: TArrayOfWideString; out numValues: Integer);
external 'ReturnsArrayOfStrings@files:Thing.dll stdcall';

procedure DoAThing;
var
  values: TArrayOfWideString;
  numValues, i: Integer;
begin
  ReturnsArrayOfStrings(values, numValues);
  for i := 0 to numValues - 1 do
  begin
    Log(values[i]);
  end;  
end;