Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - DLL -> INVALID POINTER OPERATION
peeage - Di 07.08.07 10:50
Titel: DLL -> INVALID POINTER OPERATION
Morje zusammen...
Hab da ein Problem:
Ich hab mir eine DLL mit einer funktion zusammengebastelt, an welche ein ARRAY of String übergeben wird. Die in dem ARRAY (größe = dynamisch) enthaltenen Strings werden umformatiert und in einem neuen ARRAY (result) zurückgegeben.
DLL
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26:
| [...]
type ROrdner = record Name: String; Verknuepfung: Integer; end; result_ARRAY = ARRAY of ARRAY of ROrdner;
[...]
function ADInputTOfilestructure(ARRAY_incoming: ARRAY of String): result_ARRAY stdcall; var [...] begin
[ ... CODE ... ] end;
exports ADInputTOfilestructure;
begin end. |
EXE
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28:
| [...]
type ROrdner = record Name: String; Verknuepfung: Integer; end; result_ARRAY = ARRAY of ARRAY of ROrdner;
[...]
implementation
function ADInputTOfilestructure(ARRAY_incoming: ARRAY of String): result_ARRAY; stdcall; external 'dll\Project2.dll';
[...]
procedure TForm1.Button1Click(Sender: TObject); var Ordner: result_ARRAY; begin
Ordner:= ADInputTOfilestructure(ARRAY_); showMessage(Ordner[1,1].Name); end; |
Wenn ich nun im Programm den Button betätige, bekomme ich zuerst den Inhalt von Ordner[1,1].Name ausgegeben und folgend die Meldung "INVALID POINTER OPERATION".
An dem Sourcecode in der DLL liegts keinesfalls. Ich hab es mal mit ner ganz einfachen Funktion probiert -> ARRAY of String übergeben, Inhalt von ARRAY[0] modifizieren und ARRAY zurückgeben .... Dabei kommt der gleiche Fehler.
Wenn ich aber in der DLL und im eigentlich Programm aus
Delphi-Quelltext
1: 2:
| type result_ARRAY = ARRAY of String; |
... folgendes mache ...
Delphi-Quelltext
1: 2:
| type result_ARRAY = ARRAY [0..5] of String; |
dann funktionierts wunderbar ;)
kann mir jemanden helfen?
peeage - Di 07.08.07 11:04
Das Problem hat sich soeben gelöst.
Wen es interessiert: Es muss in der DLL + im eigentlichen Programm die Unit ShareMem eingebunden werden.
Stefan.Buchholtz - Di 07.08.07 11:08
Typen mit dynamischer Speicherverwaltung (Strings, dynamische Array, Varianten) lassen sich nicht so einfach zwischen einer DLL und dem Hauptprogramm austauschen. Speicher für diese Typen wird vom Delphi-Speichermanager verwaltet, wobei Hauptprogramm und DLL jede normalerweise jeweils einen eigenen haben. Wenn man dann dynamische Typen zwischen Programm und DLL austauscht, kommen sich die gegenseitig in die Quere und es kracht.
Dafür gibt es drei Abhilfen
1.) Zum Datenaustausch nur Typen mit fester Größe (statische Arrays, Strings mit expliziter Längenangabe) verwenden.
2.) Dynamischen Speicher selbst via GetMem und FreeMem verwalten. Dabei gilt: Jeder muss seinen Speicher selbst aufräumen. Wenn die DLL Daten in einem via GetMem angeforderten Speicherbereich zurückgibt, bruachst du eine zusätzliche DLL-Funktion, um diesen Speicher auch in der DLL wieder freizugeben - macht das Hauptprogramm FreeMem auf einen Speicherblock, der in der DLL erzeugt wurde oder umgekehrt, knallt es.
3.) Den gemeinsamen Speichermanager ShareMem verwenden. Dazu müssen Hauptprogramm und DLL die Unit ShareMem jeweils als erstes in der Projektdatei einbinden. Ausserdem muss zum Programm die Delphi beigelegte BORLNDMM.DLL mit installiert werden.
Stefan
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!