![]() |
Re: Dynamisches Array von DLL übergeben
Zitat:
Würde das nicht irgendwie dem Sinn der DLL widersprechen? Ich meine du zerteilst erst etwas mit deiner Explode Funktion und dann bastelst du wieder einen String, den man um ihn in ein Array zu packen wieder mit einer Explode-artigen Funktion bearbeiten muss um das Ergebnis in ein Array zu speichern. Hört sich für mich Sinnlos an. Kannst du nicht vielleicht einen Pointer übergeben, der auf eine Speicheradresse mit dem Array zeigt? Aber das würde wahrscheinlich nur bei konstanter Größe gehen richtig? |
Re: Dynamisches Array von DLL übergeben
Pointer sind schon der richtige Weg - denke ich.
Mein Problem ist folgendes. Ich möchte einen Datensatz aus einer DB per PHP laden. Da habe ich dann verschiedene Felder (klar -> ist ja eine DB) diese Felder bzw. deren Werte sind durch einen Separator getrennt. Das Ende des Datensatzes hat einen anderen Separator. Jetzt möchte ich alle Datensätze in ein Record speichern. Dazu muss ich doch erst die Werte zurückgeben lassen (die "Sep1" getrennt) und das Ende eines Datensatzes finden ("Sep2"). Jetzt muss ich erst nach Sep2 exploden und diese in ein Array speichern, sodass ich auf die einzelnen Datensätze zugreifen kann. Dann kann ich mich an die Werte machen ("Sep1") und kann diese Daten dann schön in mein Array speichern. Soweit mein Vorhaben *g* |
Re: Dynamisches Array von DLL übergeben
Mit Pointer funktioniert das so nicht!
Das Arbeiten mit dynamischen Arrays zwischen DLL und Applikation ist, wie ich schmerzlich lernen mußte, nicht ohne weiteres möglich. Besonders dann nicht, wenn du ohne Speichermanager arbeiten willst. Ich habe mir für diesen Fall eine "Krücke" gebastelt, in dem ich das Array in der DLL verwalten lasse und mir Export-Funktionen gebaut habe, die mir u.a. die Länge des DLL-Arrays zurück geben. Die einzelnen Array-Elemente lasse ich mir mit einer weiteren Export-Funktion(Index):PChar zurück geben. Hierbei muss ich nur dafür sorgen, das ausreichend Speicher reserviert wird, sonst bekommt man nur ein Teil des String wieder zurück. Quasi überträgt man nicht das Array komplett, sondern nur die einzelnen Elemente des Arrays. Wenn du auf Applikationsseite die einzelen Elemente wieder in ein Array speicherst, dagegen spricht nix. Es ist halt nur nicht möglich das Array komplett per Parameter wieder zurück zubekommen. Zumindest nicht ohne Speichermanager. Sorry, mit Beispielcode kann ich dir augenblicklich nicht dienen. |
Re: Dynamisches Array von DLL übergeben
Frage an gmc616: Warum gibt die DLL nicht einfach zurück, wieviele Einträge es in dem Array gibt und eine weitere Funktion gibt die Adresse des ersten Eintrags an. Dies würde der Applikation doch schon reichen, schliesslich sind alle Arrays im Speicher fortlaufend und somit kann sie sich mit einem grossen CopyMemory() oder Move() Befehl den kompletten Array Inhalt kopieren ohne über jedes einzelne Element zu laufen.
|
DP-Maintenance
Dieses Thema wurde von "Daniel" von "Programmieren allgemein" nach "Sonstige Fragen zu Delphi" verschoben.
|
Re: Dynamisches Array von DLL übergeben
Hallo Muetze1,
Das habe ich schon probiert. Ich lade meine DLL dynamisch. Das Kopieren per CopyMemory funktioniert auch ohne Probleme. Wenn Ich allerdings die DLL mit FreeLibrary wieder entlade, bekomme ich eine Schutzverletzung bei Schreiben(!) an Adresse xy. Vlt. liegt es daran, dass ich mit Array of Records arbeite. Vlt. muß ich auch irdendwo wieder Speicher freigeben, wüsste aber nicht welchen. Oder es liegt daran, das es ohne Speichermanager einfach nicht funktioniert. Ich weiß es nicht. Daher die Krücke. Es wäre allerdings ne feine Sache, wenn das so einfach mit CopyMemory funktioniert täte / tun würde. :hi: gmc |
Re: Dynamisches Array von DLL übergeben
Bekomme ich hier was nicht mit? :gruebel:
Man kann doch dynamische Arrays aus einer DLL zurückgeben...
Delphi-Quellcode:
library xyz;
uses ... type TTestArray = array of ShortString; function GetTestArray: TTestArray; stdcall; begin SetLength(Result, 3); Result[0] := 'Hallo'; Result[1] := 'Welt'; Result[2] := '!'; end; exports GetTestArray; end.
Delphi-Quellcode:
*Edit: "Testprogramm" um dynamisches Einbinden der Funktion erweitert
program test_xyz;
interface type TTestArray = array of ShortString; ... var GetTestArray: function: TTestArray; stdcall; implementation procedure TestItOut; var a: TTestArray; i: Integer; hDLL: THandle; begin hDLL := LoadLibrary('xyz.dll'); if hDLL <> 0 then begin GetTestArray := GetProcAddress(hDLL, 'GetTestArray'); if GetTestArray <> nil then begin a := GetTestArray; ShowMessage(IntToStr(Length(a))); // Eine schicke "3" erscheint als Meldung for i := Low(a) to High(a) do ShowMessage(a[i]); // Hallo *click* Welt *click* ! *click* SetLength(a, 0); GetTestArray := nil; end; FreeLibrary(hDLL); end; end; |
Re: Dynamisches Array von DLL übergeben
Zitat:
Zitat:
Ansonsten Speicher des Array freigeben? Naja, SetLength(Array, 0); - aber eigentlich nicht unbedingt von nöten. Ich werde die Tage selber mal ein Beispielprojekt dazu aufbauen und das ganze nochmal im Detail versuchen nach zu vollziehen. |
Re: Dynamisches Array von DLL übergeben
Hm...
hab mir dazu nochmal gedanken gemacht und getestet (hab mit Pointern noch nie was gemacht - lerne aber gerne dazu) und einiges rumprobiert. hab zum Testen die Funktion myArray, die mir den zeiger zurückgeben soll. Eine weitere Funktion empfängt einen Zeiger und weist dementsprechend den Wert aus. Mein Programm fragt also nach einem Zeiger, empfängt ihn, sendet ihn an Funktion 2 und empfängt den String. Vom Prinzip her garnicht mal so übel (hoffe ich). Doch ich denke, mein erster Fehler liegt schon in der ersten Funktion, da ich nicht weiß, welchen Rückgabewert ich benutzen muss. Ich denke, da Integer und Pointer so ziemlich gleich sind, kann ich den Pointer in einen Integer packen, gibt aber bei der Rückgabe im Programm nur Schrott aus. Weis nicht, wie ich auf einen Pointer zugreifen kann, um dessen Wert zu bekommen.:
Delphi-Quellcode:
Danke nochmal!
function myArray: integer;
var testarr: array of byte; zeiger: ^integer; begin SetLength(testarr, 2); randomize; testarr[0]:=random(9999); testarr[1]:=32; zeiger:=@testarr[0]; result:=Integer(zeiger); end; |
Re: Dynamisches Array von DLL übergeben
Da die Array-Variable selber ein Pointer ist, kannst du auch direkt casten:
('s kommt aber darauf an, wie du es drüben verwenden willst)
Delphi-Quellcode:
oder etwas schöner ... du gibst ja einen Zeiger zurück :zwinker:
function myArray: integer;
var testarr: array of byte; begin SetLength(testarr, 2); randomize; testarr[0]:=random(9999); testarr[1]:=32; result:=Integer(testarr); end;
Delphi-Quellcode:
und zurück dann z.B. so:
function myArray: pointer;
var testarr: array of byte; begin SetLength(testarr, 2); randomize; testarr[0]:=random(9999); testarr[1]:=32; result:=pointer(testarr); end; type Ttestarr = array of byte; Ttestarr(myArray) PS: randomize; nicht ständig aufrufen! PSS: SetLength(Arr, 0); dat is schneller, da es direkt ClearArray aufruft ._. Arr := nil; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:34 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 by Thomas Breitkreuz