2016-10-11 7 views
2

Я использую Unmanaged Exports NuGet от Роберта Giesecke и имеют следующий метод в C#:Возвращение строки массив из C# для установки Inno

[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"}; 
} 

В Setup Inno Это мой код:

[Code] 
procedure DummyMethod(out Test: TArrayOfString; out Count: Integer); 
external '[email protected]: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

UnmanagedType.LPArray с string отображает массив указателей на символ (C-style char**). В Unicode Pascal Script это array of PAnsiChar. Невозможно, чтобы Pascal Script мог магически преобразовать это значение в TArrayOfString (array of string).

Вы можете преобразовать это следующим образом:

type 
    TArrayOfPAnsiChar = array of PAnsiChar; 

procedure DummyMethod(out StringPtrs: TArrayOfPAnsiChar; out Count: Integer); 
    external '[email protected]: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; 

(протестированные с программой установки Unicode Inno)


Боковые ноты:

  • Это не ясно, кто делает выделение памяти для TArrayOfAnsiChar и отдельных массивов символов. В лучшем случае я чувствую утечку памяти.
  • Возможно, вы захотите использовать 16-разрядный буфер символов, а не 8-разрядный буфер символов, чтобы разрешить полный Unicode. Хотя обратите внимание, что это сложнее реализовать в скрипте Pascal, поскольку ему не хватает 16-разрядного типа указателя символов.
+2

Ваш ответ был полезен, и предоставленный код работает отлично. Преобразование из строки [] в char ** действительно имеет смысл. У меня не было большого опыта работы с такими установками, и мои знания за пределами управляемого кода довольно ограничены. Мне пришлось переключиться с не-unicode на unicode Inno Setup, но я считаю, что это хорошо! :) – breez