![]() |
Dyn Array of Record aus DLL
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:
Das ich ohne Speichermanager arbeiten will, reicht es der Dll-Funktion einen Zeiger auf das Record zugeben.
unit MyRecords;
... type TSimpleRecord = record Zeile1 : String; Zeile2 : String; end; type TPSimpleRecord = ^TSimpleRecord; var MyRecord : TSimpleRecord; MyPointer : TPSimpleRecord; Das Hauptprogramm:
Delphi-Quellcode:
Die DLL:
unit AppMain;
... procedure FillRecord (APointer:TPSimpleRecord); stdcall; external 'MyDll.dll'; ... MyPointer := @MyRecord; FillRecord (MyPointer); ShowMessage (MyRecord.Zeile1);
Delphi-Quellcode:
Ich hoffe der Code ist soweit korrekt. Funktionieren tut er jedefalls. :zwinker:
library MyDll;
... procedure FillRecord (APointer : TPSimpleRecord); stdcall; begin APointer^.Zeile1 := 'erste Zeile'; APointer^.Zeile2 := 'zweite Zeile'; end; Nun habe ich aber das Problem, das mein Record weitere Array of Record enthalten muß. z.B. so:
Delphi-Quellcode:
Füllen des Record wollte ich ähnlich machen w.o.:
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;
Delphi-Quellcode:
Die Funktion in der DLL sieht dann z.B. so aus:
Unit AppMain;
... procedure FillDynRecord (APointer:TPDynRecord); stdcall; external 'MyDll.dll'; ... MyDynPointer := @MyDynRecord; FillRecord (MyDynPointer);
Delphi-Quellcode:
Das Füllen des DynRecords in der DLL funktioniert.
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; 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 |
Re: Dyn Array of Record aus DLL
Kann mir keiner Helfen??
Ich habe heute festgestellt, dass das Problem nur mit dynamisch geladenen DLL's besteht. Ich übergebe den Pointer des Records in die DLL und die Dll füllt das Record korrekt. Erst wenn ich die Dll im Hauptprogramm aus dem Speicher mit FreeLibrary entlade ist mein Record zerstört bzw. nicht verfügbar. Wieso? Das Record gehört doch der Hauptanwendung und die DLL bekommt nur einen Zeiger darauf? :gruebel: das ist mir zu hoch :freak: |
Re: Dyn Array of Record aus DLL
Du Arbeitest mit Delphi-Strings. Da brauchst du den Speichermanager sonst krachst.
Du könntest aber mit PChar arbeiten dann dürfte das Problem gelößt sein wenn du korrekt den Speicher für diese Strings von Windows holst und nicht über den Delphi-MM. Oder du nimmst z.B. Zeile1 : array[0..10000] of char ist aber 'ne gewaltige Speicherverschwendung. |
Re: Dyn Array of Record aus DLL
Hmmm ... pchar also. Den Typ verwende ich sonst auch für die Übergabe von Strings in DLLs.
Eine Speichermanager will/kann/darf ich nicht verwenden, da meine Anwendung mit einer weiteren DLL arbeitet, die sich mit dem Delphi-Speichermanager nicht verträgt (laut Dokumentation, und tut sie auch nicht). Was passiert eigentlich im Speicher wenn ich der Delphi-DLL a) einen String, b) ein PChar, c) einen Zeiger auf einen String übergebe ?? gibt es da irgendwo etwas zum nachlesen? Ich habe aus dem DynRecord mal ein Object ( = class (TObject) ) gemacht und ebenfalls den Zeiger in die DLL gegeben. Das gleiche. Nach FreeLibrary ist das Object zerstört. Ich dachte bis jetzt, dass bei der "normalen" Übergabe von Variablen eine Kopie im Speicher stellt mit der dann (im meinem Fall die DLL) weiter gearbeitet wird. Da die Übergabe von Delphi-Strings in eine DLL ohne Speichermanager nicht funktioniert, dachte ich mir, ich zeige der DLL wo die Daten stehen indem ich nur einen Pointer rüber reiche. So gebe ich der DLL quasi nur eine Zahl, die Daten stehen im Adressbereich der Hauptanwendung und ich kann auf den Speichermanager verzichten. Naja, freilich das klapp solange wie sich die Größe der Daten nicht ändert ... :| Das scheint wohl mein Denkfehler zu sein. :gruebel: Aber wie denkt man es richtig? :stupid: Ich werde erst mal die Strings in PChar ändern. Mal sehen ob das klappt. Wie holt man Speicher für diese "Strings" korrekt? |
Re: Dyn Array of Record aus DLL
Zitat:
Hast Du schon mal probiert ob du mit FastMM arbeiten könntest? Zitat:
Zitat:
Zitat:
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:00 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz