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

时间:2011-05-13 08:40:18

标签: c# delphi dll pinvoke

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

3 个答案:

答案 0 :(得分:1)

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

<强>的Delphi

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代码的数组大小,以便它可以分配用于存储值的内存。

我不会继续谈论为什么我做了某些事情。从以前的问题我认为你有足够的专业知识来从这个代码中解决。如果您有任何疑问,请发表评论,我会尽力解决问题!

答案 1 :(得分:0)

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

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

此示例将“PChar”的其他类型传递给DLL。您也可以将指针传递给您的数组。

答案 2 :(得分:-1)

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