如何从 C# 应用程序向 Delphi DLL 发送和接收 2D 数组

本文关键字:数组 2D DLL 应用程序 Delphi | 更新日期: 2023-09-27 17:56:14

我正在编写一个C#应用程序,它将在其中调用用Delphi编写的DLL。我有Delphi DLL的源代码。我想将一个 2D 数组从 C# 发送到 DLL,DLL 创建另一个 2D 数组并将其发送回 C# 代码。我该怎么做?

如何从 C# 应用程序向 Delphi DLL 发送和接收 2D 数组

我已经为您编写了一些 2D 数组的示例代码。 这有点混乱,因为编组器不会自然地处理 2D 数组。 相反,我选择将数组展平,即将它们编组为 1D 数组。 这不会有很好的性能特征,但也许这对你来说并不重要。 只有你能知道。

德 尔 福

library mydll;
var
  arr: array of array of Double;
procedure ManagedToNative(RowCount, ColCount: Integer; Values: PDouble); stdcall;
var
  r, c: Integer;
begin
  SetLength(arr, RowCount, ColCount);
  for r := 0 to RowCount-1 do begin
    for c := 0 to ColCount-1 do begin
      arr[r,c] := Values^;
      inc(Values);
    end;
  end;
end;
procedure NativeToManaged(out RowCount, ColCount: Integer; Values: PDouble); stdcall;
var
  r, c: Integer;
begin
  RowCount := Length(arr);
  if RowCount>0 then begin
    ColCount := Length(arr[0]);
  end else begin
    ColCount := 0;
  end;
  if Assigned(Values) then begin
    for r := 0 to RowCount-1 do begin
      for c := 0 to ColCount-1 do begin
        Values^ := arr[r,c];
        inc(Values);
      end;
    end;
  end;
end;
exports
  ManagedToNative,
  NativeToManaged;
begin
end.

C#

using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
    class Program
    {
        [DllImport(@"mydll.dll")]
        private static extern void ManagedToNative(int RowCount, int ColCount, double[] Values);
        [DllImport(@"mydll.dll")]
        private static extern void NativeToManaged(out int RowCount, out int ColCount, double[] Values);
        static double[] Flattened(int RowCount, int ColCount, double[,] arr)
        {
            double[] result = new double[RowCount*ColCount];
            int i = 0;
            for (int r = 0; r < RowCount; r++)
                for (int c = 0; c < ColCount; c++)
                {
                    result[i] = arr[r,c];
                    i++;
                }
            return result;
        }
        static double[,] Expanded(int RowCount, int ColCount, double[] arr)
        {
            double[,] result = new double[RowCount,ColCount];
            int i = 0;
            for (int r = 0; r < RowCount; r++)
                for (int c = 0; c < ColCount; c++)
                {
                    result[r,c] = arr[i];
                    i++;
                }
            return result;
        }
        static void Main(string[] args)
        {
            const int RowCount = 6;
            const int ColCount = 9;
            double[,] arr = new double[RowCount,ColCount];
            for (int r = 0; r < RowCount; r++)
                for (int c = 0; c < ColCount; c++)
                    arr[r,c] = r*c;
            ManagedToNative(RowCount, ColCount, Flattened(RowCount, ColCount, arr));
            int myRowCount, myColCount;
            NativeToManaged(out myRowCount, out myColCount, null);
            double[] flat = new double[myRowCount * myColCount];
            NativeToManaged(out myRowCount, out myColCount, flat);
            double[,] expanded = Expanded(myRowCount, myColCount, flat);
            for (int r = 0; r < RowCount; r++)
                for (int c = 0; c < ColCount; c++)
                    System.Console.WriteLine(arr[r, c] - expanded[r, c]);
        }
    }
}

该代码将 2D 数组从 C# 传递到 Delphi,并存储该数组。 然后 C# 代码会要求返回它。 WriteLine()语句显示返回的值与传递的值相同。

我已经安排NativeToManaged()返回数组的维度,即使这段代码已经知道它们。 实际上,您的 C# 代码可能希望向 Delphi 代码询问数组大小,以便它可以分配用于存储值的内存。

不会继续谈论我为什么做某些事情。 从前面的问题中,我认为您有足够的专业知识来从此代码中解决它。 如果您有任何疑问,请发表评论,我会尽力阐明一些信息!

可以在 C# 之外的 DLL 中进行函数调用,并且可以传递参数。您的 2D 数组是一种类型或类,可以作为参数传递。这里有一个很好的解释,如何从C#调用Delphi-DLL:

http://tek-tips.com/faqs.cfm?fid=7416

此示例将"PChar"另一种类型传递给 DLL。您也可以将指针传递给数组。

我认为您可以以xml或其他格式传输数据,然后在Delphi应用程序或.NET中进行反序列化