如何使用非托管导出(Robert Giesecke)将dateTime类型数组从.NET传递到Delphi?

时间:2016-08-27 02:24:14

标签: c# arrays delphi datetime

我想将.NET dll中的dateTime类型数组传递给Delphi。 这是c#代码:

[DllExport]
public static void ReadDateTimeData(out IntPtr unmanagedArray, out int length)
{
    //Get the DateTimeArray
    DateTime[] dateTimeArray = MyClass.Instance.GetDateTimeArray();
    length = dateTimeArray.Length;

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

但是Marshal.Copy()方法不支持将DateTime类型数组添加到非托管内存指针。我该怎么办?另外,如何实现delphi代码?

1 个答案:

答案 0 :(得分:3)

如果您的日期时间值在自动化兼容范围内,则可以使用DateTime.ToOADate()获取与自动化兼容的值,然后只使用Marshal.Copy的重载代替double[]:< / p>

public static void ReadDateTimeData(out IntPtr unmanagedArray, out int length)
{
    // Get the DateTimeArray
    DateTime[] dateTimeArray = GetDateTimeArray();
    length = dateTimeArray.Length;
    // Convert to double[]
    double[] oaDateArray = new double[length];
    for (int i = 0; i < length; i++)
        oaDateArray[i] = dateTimeArray[i].ToOADate();

    unmanagedArray = Marshal.AllocHGlobal(length * Marshal.SizeOf(typeof(double)));
    Marshal.Copy(oaDateArray, 0, unmanagedArray, length);
}

在Delphi端,您将收到指向TDateTime数组的指针:

procedure ReadDateTimeData(out DateTimeArray: PDateTime; out Length: Integer); stdcall; external 'TestLib.dll';
procedure FreeDateTimeData(DateTimeArray: PDateTime); stdcall; external 'TestLib.dll';

procedure Main;
var
  DateTimeArray, P: PDateTime;
  I, Len: Integer;
begin
  ReadDateTimeData(DateTimeArray, Len);
  try
    P := DateTimeArray;
    for I := 0 to Len - 1 do
    begin
      Writeln(DateTimeToStr(P^));
      Inc(P);
    end;
  finally
    FreeDateTimeData(DateTimeArray);
  end;
end;

或者,范围检查:

type
  PDateTimeArray = ^TDateTimeArray;
  TDateTimeArray = array[0..0] of TDateTime;

procedure ReadDateTimeData(out DateTimeArray: PDateTimeArray; out Length: Integer); stdcall; external 'TestLib.dll';
procedure FreeDateTimeData(DateTimeArray: PDateTimeArray); stdcall; external 'TestLib.dll';

procedure Main;
var
  DateTimeArray: PDateTimeArray;
  I, Len: Integer;
begin
  ReadDateTimeData(DateTimeArray, Len);
  try
    for I := 0 to Len - 1 do
      Writeln(DateTimeToStr(DateTimeArray^[I]));
  finally
    FreeDateTimeData(DateTimeArray);
  end;
end;