Autor Beitrag
peeage
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 50



BeitragVerfasst: Di 07.08.07 10:50 
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

ausblenden 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

ausblenden 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_);     // Hier wird ein ARRAY of String an die Funktion in der DLL übergeben
  showMessage(Ordner[1,1].Name);               // Hier soll Testweiste ein Inhalt des Rückgabearrays ausgegeben werden

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

ausblenden Delphi-Quelltext
1:
2:
type
  result_ARRAY = ARRAY of String;


... folgendes mache ...

ausblenden Delphi-Quelltext
1:
2:
type
  result_ARRAY = ARRAY [0..5of String;



dann funktionierts wunderbar ;)


kann mir jemanden helfen?
peeage Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 50



BeitragVerfasst: 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.

ausblenden Delphi-Quelltext
1:
uses ShareMem;					
Stefan.Buchholtz
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 612

WIN 2000, WIN XP, Mac OS X
D7 Enterprise, XCode, Eclipse, Ruby On Rails
BeitragVerfasst: 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

_________________
Ein Computer ohne Windows ist wie eine Schokoladentorte ohne Senf.