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