Unmanaged Exports with Arrays

℡╲_俬逩灬. 提交于 2019-12-06 09:54:52

You have to allocate the array in a way that it isn't affected by the GC. You do that with Marshal.AllocHGlobal:

[DllExport]
static void GetVals(out IntPtr unmanagedArray, out int length)
{
    var valueList = new[]
    {
        1, 2, 3
    };

    length = valueList.Length;

    unmanagedArray = Marshal.AllocHGlobal(valueList.Length * Marshal.SizeOf(typeof(int)));
    Marshal.Copy(valueList, 0, unmanagedArray, length);
}

On the Delphi side, you will get a pointer to the first element, and the size. To read it you can increment the pointer arraySize-1 times and put it into a list or a Delphi-managed array:

uses
  SysUtils,
  Windows;

  procedure  GetVals(out unmanagedArray : PInteger; out arraySize : Integer);
    stdcall;
    external 'YourCSharpLib';

  function GetValsAsArray : TArray<integer>;
  var
    unmanagedArray, currentLocation : PInteger;
    arraySize, index : Integer;
  begin
    GetVals(unmanagedArray, arraySize);
    try
      SetLength(result, arraySize);
      if arraySize = 0 then
        exit;

      currentLocation := unmanagedArray;

      for index := 0 to arraySize - 1 do
      begin
        result[index] := currentLocation^;
        inc(currentLocation);
      end;
    finally
      LocalFree(Cardinal(unmanagedArray));
    end;
  end;

var
  valuesFromCSharp : TArray<integer>;
  index : Integer;
begin
  valuesFromCSharp := GetValsAsArray();

  for index := low(valuesFromCSharp) to high(valuesFromCSharp) do
    Writeln(valuesFromCSharp[index]);
end.
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!