开发者

How to send and receive 2D arrays from C# application to Delphi DLL?

I am writing a C# application in which it would call a DLL that was written in Delphi. I have the source code of Delphi DLL. I want to send a 2D array from C# to DLL and the DLL create开发者_如何学运维s another 2D array and send it back to C# code. How can I do this?


I've written you some sample code for 2D arrays. It's a bit messy because the marshaller won't naturally handle 2D arrays. Instead I've opted for flattening the arrays, i.e. marshall them as 1D arrays. This won't have great performance characteristics but perhaps that won't be significant for you. Only you can know that.

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]);
        }
    }
}

The code passes a 2D array from C# to Delphi where it is stored. Then the C# code asks for it back. The WriteLine() statements show that the same values are returned as were passed.

I have arranged for NativeToManaged() to return the dimensions of the array even though this code already knows them. In reality your C# code is likely going to want to ask the Delphi code for the array size so that it can allocate memory in which to store the values.

I won't go on and on about why I've done certain things. From previous questions I think you have enough expertise to work it out from this code. If you do have any questions, leave a comment and I'll do my best to shed some light!


A function-call in the DLL out of C# is possible and you can pass parameters. Your 2D-array is a type or a class, this can be passed as parameter. Here is a good explanation how to call a Delphi-DLL out of C#:

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

This example passes "PChar" an other types to the DLL. You can pass pointers to your array also.


I think you can transmit the data in an format like xml or other and then deserialize in Delphi application or .NET

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜