2009-10-05 18 views
5

Ich versuche, eine Prozedur in einer Delphi-DLL von C# aufzurufen. Die Prozedur erwartet, dass der Aufrufer eine array of array of TSomeRecord vorerfasst und eingibt, von der er dann die TSomeRecord Elemente manipuliert, um Ergebnisse zurückzugeben. Also, ich muss Delphi dynamische Felder Arrays von X in Handarbeit machen.
Jetzt, I have found here, dass eine dynamische array of X besteht aus einem Zeiger auf das erste Element des dynamischen Arrays, und dass dieses erste Element eine Referenzzahl und die Länge hat (Anzahl der Elemente) des Feldes vorangestellt (jeweils 32-Bit-Ganzzahlen), und dass die Elemente inline und zusammenhängend gespeichert werden, so dass das ganze so aussieht Speicher:Wie ist das Speicherlayout eines dynamischen Delphi-Arrays des dynamischen Arrays von X?

 
rrrrllll000...000111...12... 
     ^

mit rrrr der Referenzzählwert , llll die Länge,die Elemente und^wohin der Zeiger zeigt. Dies bestätigt; Ich habe es getestet und es funktioniert.
für mehrdimensionale dynamische Arrays I angenommen, dass ich array of Y für die X in array of X, mit anderen Worten, dass die äußere Dimension Arrays ein dynamisches Array von (Zeiger) ist einfach ersetzen kann dynamisch, etwa so:

 
rrrrllll000011112222... 
     ^

wobei die Elemente 0000, 1111 usw. nun 32-Bit-Zeiger für unabhängig zugeordnete dynamische Arrays sind. Wenn ich so vorgehe, erhalte ich eine Zugriffsverletzung für meine Probleme. Das ist offensichtlich nicht, wie Delphi es von mir erwartet. Kann mir jemand erklären wie ich das am soll?

Antwort

8

Ein dynamisches Array ist ein Zeiger auf einen gepackten Block von Elementen.

Also Array von Array von TSomeRecord ist ein Zeiger auf ein Array von Zeigern, von denen jeder auf einen Blockspeicher mit der Länge (Array [firstlevel]) Elemente oder Null, wenn keine sind.

Mit anderen Worten, was Sie annehmen, ist in etwa richtig, mit dem Zusatz, dass Arrays mit Nullelementen Null sind. Beachten Sie, dass Sie Referenzzählung und -länge nicht ändern sollten, es sei denn, Sie wissen WIRKLICH, was Sie tun.

Das Bestimmen, was Ihren Absturz verursacht, wird ohne Beispielcode schwer sein. Beachten Sie, dass, wie für ALLE automatisierte Delphi-Typen (außer Widestring), alle dynamischen Speicher vom Delphi-Speicher-Manager zugeordnet werden müssen.

Versuche, den Speichermanager der Sprache zu verwenden, mit der Sie eine Schnittstelle herstellen, ist nicht möglich.

+0

Danke für Ihre Antwort. Ich weiß, dass dies mit (Beispiel) Code leichter zu diagnostizieren ist, aber ich habe keinen; nur die Signatur des Verfahrens. Die DLL ist eine Blackbox von Drittanbietern. –

+0

Dann ist der einzige Rat, den ich Ihnen geben kann, an dem Prinzip zu bleiben, dass derjenige, der auch zuweist, die Zuordnung aufheben muss oder die DLL in Delphi in ein Delphi umbrechen muss.exe (comserver) oder dll zuerst, die die automatisierten Typen von der Schnittstelle entfernt –

0

The Language Guide (einmal als sehr nützlich Handbücher gedruckt, jetzt diese Informationen in der Online-Hilfe zu finden, ist sehr schwer) heißt es:

„Ein mehrdimensionales Array mit der äußersten rechten Dimension zu erhöhen ersten gespeichert ist.“

Dabei AFAIK haben Sie nicht eine Reihe von Zeigern - einfach jede Dimension Daten nacheinander, angefangen von der ganz rechten, ich denke, es ist schneller, weil es keine Umleitungen mehr gibt.

+0

Das LG-Fragment ist über statische Arrays, während die Frage über dynamische Arrays ist. –

+0

Sie haben Recht. Ich habe das Handbuch überprüft und obwohl das Speicherlayout von dynamischen Arrays nicht detailliert ist, sagt es Dynarray kann "nicht rechteckig" sein, und ich denke, der einzige Weg, es zu erreichen, ist ein dynamisches Array als Elemente des "äußeren" Array. Ziemlich langsam, um jedoch auf die inneren zuzugreifen. –

Verwandte Themen