Как отправлять и получать 2D-массивы из приложения C # в Delphi DLL? - PullRequest
0 голосов
/ 13 мая 2011

Я пишу приложение на C #, в котором оно будет вызывать DLL, написанную на Delphi. У меня есть исходный код Delphi DLL. Я хочу отправить 2D-массив из C # в DLL, и DLL создаст другой 2D-массив и отправит его обратно в код C #. Как я могу это сделать?

Ответы [ 3 ]

1 голос
/ 14 мая 2011

Я написал вам пример кода для 2D-массивов. Это немного грязно, потому что маршаллер не будет работать с двумерными массивами. Вместо этого я выбрал сглаживание массивов, то есть их маршалирование как одномерных массивов. Это не будет иметь хороших характеристик производительности, но, возможно, это не будет иметь для вас значения Только ты можешь знать это.

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

Код передает двумерный массив из C # в Delphi, где он хранится. Затем код C # запрашивает его обратно. Операторы WriteLine() показывают, что возвращаются те же значения, что и переданные.

Я организовал для NativeToManaged() возвращение размеров массива, хотя этот код уже знает их. На самом деле ваш код C #, вероятно, захочет запросить код Delphi для размера массива, чтобы он мог выделить память для хранения значений.

Я не буду говорить о том, почему я сделал определенные вещи. Из предыдущих вопросов я думаю, что у вас достаточно опыта, чтобы разобраться в этом коде. Если у вас есть какие-либо вопросы, оставьте комментарий, и я сделаю все возможное, чтобы пролить свет!

0 голосов
/ 13 мая 2011

Возможен вызов функции в DLL из C #, и вы можете передавать параметры. Ваш 2D-массив является типом или классом, это можно передать как параметр. Вот хорошее объяснение, как вызвать Delphi-DLL из C #:

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

Этот пример передает «PChar» другие типы в DLL. Вы также можете передавать указатели на ваш массив.

0 голосов
/ 13 мая 2011

Я думаю, что вы можете передавать данные в формате, таком как XML или другой, а затем десериализовать в приложении Delphi или .NET

...