Einzelnen Beitrag anzeigen

gmc616

Registriert seit: 25. Jun 2004
Ort: Jena
627 Beiträge
 
Delphi 10.3 Rio
 
#1

Dyn Array of Record aus DLL

  Alt 22. Nov 2006, 17:33
Hallo DPler,

ich möchte ein Record in einer DLL füllen. Dazu habe ich in einer separaten Unit, die sowohl vom Hauptprogramm als auch der DLL verwendet wird, das Record definiert. z.B. so:
Delphi-Quellcode:
unit MyRecords;
...
type TSimpleRecord = record
  Zeile1 : String;
  Zeile2 : String;
end;

type TPSimpleRecord = ^TSimpleRecord;

var
  MyRecord : TSimpleRecord;
  MyPointer : TPSimpleRecord;
Das ich ohne Speichermanager arbeiten will, reicht es der Dll-Funktion einen Zeiger auf das Record zugeben.
Das Hauptprogramm:
Delphi-Quellcode:
unit AppMain;
...
procedure FillRecord (APointer:TPSimpleRecord); stdcall; external 'MyDll.dll';
...
MyPointer := @MyRecord;
FillRecord (MyPointer);
ShowMessage (MyRecord.Zeile1);
Die DLL:
Delphi-Quellcode:
library MyDll;
...
procedure FillRecord (APointer : TPSimpleRecord); stdcall;
begin
  APointer^.Zeile1 := 'erste Zeile';
  APointer^.Zeile2 := 'zweite Zeile';
end;
Ich hoffe der Code ist soweit korrekt. Funktionieren tut er jedefalls.

Nun habe ich aber das Problem, das mein Record weitere Array of Record enthalten muß. z.B. so:
Delphi-Quellcode:
unit MyRecords;
...
type TSimpleRecord = record
  Zeile1 : String;
  Zeile2 : String;
end;

type TDynRecord = record
  Name : string;
  Zeilen : array of TSimpleRecord;
end;

type TPDynRecord = ^TDynRecord;

var
  MyDynRecord : TDynRecord;
  MyDynPointer : TPDynRecord;
Füllen des Record wollte ich ähnlich machen w.o.:
Delphi-Quellcode:
Unit AppMain;
...
procedure FillDynRecord (APointer:TPDynRecord); stdcall; external 'MyDll.dll';
...
MyDynPointer := @MyDynRecord;
FillRecord (MyDynPointer);
Die Funktion in der DLL sieht dann z.B. so aus:
Delphi-Quellcode:
library MyDll;
...
procedure FillDynRecord (APointer : TPDynRecord); stdcall;
begin
  APointer^.Name := 'Test';
  Setlength(APointer^.Zeilen,2);
  APointer^.Zeilen[0].Zeile1 := 'erste Zeile';
  APointer^.Zeilen[0].Zeile2 := 'zweite Zeile';
  APointer^.Zeilen[1].Zeile1 := 'dritte Zeile';
  APointer^.Zeilen[1].Zeile2 := 'vierte Zeile';
end;
Das Füllen des DynRecords in der DLL funktioniert.

Wenn allerdings die Anwendung wieder zurück ins HauptProgramm springt, ist dort mein DynRecord "nicht verfügbar" und bei Rücksprung aus der Function, die FillDynRecord gerufen hat, stürzt die Anwendung mit einer Schutzverletzung beim Speicherzugriff an Adresse xy ab.

Ich vermute, das beim Vergrößern des Array of Record mit setlength() irgendwas im Speicher überschrieben wird.

Was muss ich tun, damit das Dynamische Array of Record korrekt zurück gegeben wird?

Danke vorab schon mal für eure Hilfe.
gmc
  Mit Zitat antworten Zitat