Tablica dwuwymiarowa jako parametr do zarządzalnego kodu dll napisanej w C#

0

Pół dnia się meczyłem zanim docztałem że tablica dynamiczna typy Array of Array nie zajmuje w pamięci obszaru ciagłego :-(.

Rozwiazałem problem zamieniając tablice 2D na tabicę jednowymiarowa z wyliczaniem indeksu wiersza i kolumny.

Czy jest bardziej elegancki sposób przekazania tablicy 2D z delphi(2007) do dll-ki napisanej w zarządzalnym kodzie C# (bez konwersji na tablice jednowymiarową) ?.

Moje rozwiazanie :
Delphi :

function ksort( handle: integer; p : PIntegerArray; size,rows,cols: Integer):Integer;stdCall;external 'csharpei.dll';

...

procedure TMainForm.testsuperobject1Click(Sender: TObject);
  var i,r,c,j, n: Integer;
      a: array of Integer;
begin
  r:= Length(digits);
  c:= Length(digits[0]);
  n:= r * c;
  setLength(a,n);
  for i:=0 to r-1 do
    for j:=0 to c-1 do
        a[i*c+j] := digits[i,j];
  ksort(main.MainForm.Handle,PIntegerArray(a),n,r,c);
end;

C#:

	  [DllExport("ksort", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]                         
	  public static void ksort ( int handle, IntPtr ptr, int len, int rows,int cols) {

		Int32[] tab = new Int32[len];

		Marshal.Copy(ptr,tab,0,len);
1

Jeżeli bloki pamięci takiej macierzy faktycznie są porozrzucane, to innego wyjścia niż ich złączenie w jeden blok nie ma; Za to w przypadku przepisywania liczb z jednej macierzy do drugiej, można to zrobić nieco inaczej, kopiując całe wiersze instrukcją Move; Trzeba tylko pamiętać o ilości kopiowanych bajtów, mnożąc ilość liczb w wierszu przez SizeOf(Integer);

PS: Drugi parametr importowanej funkcji powinien być typu PInteger, bo to wskaźnik na pojedynczą liczbę, a nie na macierz.

1 użytkowników online, w tym zalogowanych: 0, gości: 1