AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Dynamisches Array in DLL kann nicht erweitert werden
Thema durchsuchen
Ansicht
Themen-Optionen

Dynamisches Array in DLL kann nicht erweitert werden

Ein Thema von devidespe · begonnen am 22. Feb 2017 · letzter Beitrag vom 7. Mär 2017
Antwort Antwort
Seite 1 von 2  1 2      
devidespe

Registriert seit: 7. Sep 2006
Ort: Berlin
434 Beiträge
 
Delphi 10.4 Sydney
 
#1

Dynamisches Array in DLL kann nicht erweitert werden

  Alt 22. Feb 2017, 16:39
Hallo,

ich habe in meinem DLL-Code eine Prozedur, die ein dynamisches Array zurückliefern soll.

Die Prozedur beginnt mit:

procedure GetValues(Config : ConfigRec; var Ergebnis : Array of SingleDataSet); und SingleDataSet ist deklariert als:

Delphi-Quellcode:
type SingleDataSet = packed record
       DataSetNr : Byte;
       DataSetName : string[30];
       DataSetValue : Integer;
       SavingTime : TDateTime;
     end;
Das kompiliert auf den ersten Blick fehlerfrei durch.

Wenn ich allerdings in der selben Prozedur das Array erweitern möchte, um Daten anzufügen, scheitert dies:

SetLength(Ergebnis, 2); mit Fehler E2008 Inkompatible Typen. Wie kann ich das trotzdem bewerkstelligen in Verbindung mit einem dynamischen Array?
Devid
57 65 72 20 6C 65 73 65 6E 20 6B 61 6E 6E 2C 20 69 73 74 20 6B 6C 61 72 20 69 6D 20 56 6F 72 74 65 69 6C 21
  Mit Zitat antworten Zitat
Fritzew

Registriert seit: 18. Nov 2015
Ort: Kehl
678 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Dynamisches Array in DLL kann nicht erweitert werden

  Alt 22. Feb 2017, 16:56
Standardmässig benutzen Programm und Dll verschiedene Speichermanager.
Das bedeutet das in einer DLL Schnittstelle nur einfache typen wie integer, double, Pchar, etc verwendet werden sollten.
Du kannst die Unit Sharemem mit einbinden. Funktioniert aber nur wenn die DLL und das Programm mit Delphi kompiliert werden.
Das nächste Problem:
die Deklaration von
var Ergebnis : Array of SingleDataSet Das ist ein OpenArray. http://docwiki.embarcadero.com/RADSt...eters_(Delphi)

Am besten Du deklarierst einen Typ für das Array:

type tSingleDatasetArray = Array of SingleDataSet; Ich wäre aber sehr vorsichtig mit solchen Parametern über eine Dll.
Am besten stelle auf packages um. (dafür sind diese gedacht).
Da die Dll ja sowieso Delphi Only ist mit solchen Parameter würde ich diesen Weg gehen.
Fritz Westermann
  Mit Zitat antworten Zitat
Sailor

Registriert seit: 20. Jul 2008
Ort: Balaton
112 Beiträge
 
Delphi 2010 Professional
 
#3

AW: Dynamisches Array in DLL kann nicht erweitert werden

  Alt 22. Feb 2017, 16:59
Array of SingleDataSet ist ein OpenArray-Parameter, kein dynamisches Feld.
Richtig geht es so:
Delphi-Quellcode:
TSingleDataSetArray = Array of SingleDataSet;

procedure GetValues(var Ergebnis:TSingleDataSetArray);
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.610 Beiträge
 
Delphi 10.3 Rio
 
#4

AW: Dynamisches Array in DLL kann nicht erweitert werden

  Alt 23. Feb 2017, 08:48
Ich würde die Länge des Arrays auch schon vor dem Aufruf setzen. Da es sich hier ja um einen Referenzparameter handelt, könntest du dir noch eine zusätzliche Funktion bauen, die dir die benötigte Länge zurückgibt.

Sowas in der Art:

Delphi-Quellcode:
procedure SomeMethod;
var
  Count: Integer;
  MyArray: TSingleDataSetArray;
begin
  if MyDllInstance.GetElementCount(Count) then begin
    SetLength(MyArray, Count);
    GetValues(MyArray);
  end;
end;
So habe ich es in meinen DLLs aufgebaut und das funktioniert wunderbar. Erinnert in abgewandelter Form auch an die Win32API bei der das ähnlich gelöst wird. Erst die Methode mit dem Referenzparamenter nil aufrufen um sich die benötigte Länge zu holen, dann die Länge des Arrays setzen und dann die Methode mit dem richtigen Array Parameter wieder ausführen.
  Mit Zitat antworten Zitat
devidespe

Registriert seit: 7. Sep 2006
Ort: Berlin
434 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Dynamisches Array in DLL kann nicht erweitert werden

  Alt 23. Feb 2017, 15:25
Array of SingleDataSet ist ein OpenArray-Parameter, kein dynamisches Feld.
Richtig geht es so:
Delphi-Quellcode:
TSingleDataSetArray = Array of SingleDataSet;

procedure GetValues(var Ergebnis:TSingleDataSetArray);
Hallo und erstmal danke für die Rückmeldung. Dein Ansatz funktioniert auf den ersten Blick, aber sobald die Prozedur beginnt, erhalte ich eine Exception bzw. "Access Violation read of address 0xffffffff". Daher habe ich einfacherweise mal den Record weggelassen, und folgendes deklariert:

Delphi-Quellcode:
type TIntegerArray = Array of integer;
...
procedure GetValues(Config : ConfigRec; var Ergebnis : TIntegerArray);
...
leider mit dem gleichen Ergebnis. Innerhalb der Prozedur mache ich noch nichtmal was mit dem "Ergebnis", weder Größenanpassungen noch sonst was. Aber es wird leider jedesmal mit der Exception quittert.
Devid
57 65 72 20 6C 65 73 65 6E 20 6B 61 6E 6E 2C 20 69 73 74 20 6B 6C 61 72 20 69 6D 20 56 6F 72 74 65 69 6C 21
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.270 Beiträge
 
Delphi 10.4 Sydney
 
#6

AW: Dynamisches Array in DLL kann nicht erweitert werden

  Alt 23. Feb 2017, 15:41
Hallo,
hast du denn ShareMem eingebunden?
Heiko
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.610 Beiträge
 
Delphi 10.3 Rio
 
#7

AW: Dynamisches Array in DLL kann nicht erweitert werden

  Alt 23. Feb 2017, 16:28
Oder der Methode noch die Direktive stdcall; mitgeben. Das sollte dann auch funktionieren.
  Mit Zitat antworten Zitat
Fritzew

Registriert seit: 18. Nov 2015
Ort: Kehl
678 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Dynamisches Array in DLL kann nicht erweitert werden

  Alt 23. Feb 2017, 16:39
Oder der Methode noch die Direktive stdcall; mitgeben. Das sollte dann auch funktionieren.
Was hat das mit der stdcall (Aufrufkonvention) zu tun?
Das beeinflusst in keiner Weise das Speichermanagement, sondern nur wie übergebene Parameter auf dem Stack behandelt werden beim verlassen der Routine. Das hat nichts mit dem allozieren von Speicher zu tun. Ohne Sharemem wird das nicht funktionieren.
Damit dynamische Arrays und auch Strings mit Dll's funktionieren muss der gleiche Speichermanager benutzt werden
Fritz Westermann

Geändert von Fritzew (23. Feb 2017 um 16:57 Uhr)
  Mit Zitat antworten Zitat
devidespe

Registriert seit: 7. Sep 2006
Ort: Berlin
434 Beiträge
 
Delphi 10.4 Sydney
 
#9

AW: Dynamisches Array in DLL kann nicht erweitert werden

  Alt 27. Feb 2017, 11:47
Nachdem ich nun alle Vorschläge ausprobiert habe und Packages ausscheiden, half mir die Direktive:

stdcall;

innerhalb der DLL, und nun wird der OpenArray-Parameter korrekt in beide Richtungen übergeben.

ShareMem hatte ich auch versucht, allerdings gelang es auch ohne und soweit ich das verstanden habe, macht es nur Sinn, wenn die Applikation, welche später auf die DLL zugreift, auch eine Delphi-Applikation ist - was bei mir aber definitiv nicht der Fall ist.
Devid
57 65 72 20 6C 65 73 65 6E 20 6B 61 6E 6E 2C 20 69 73 74 20 6B 6C 61 72 20 69 6D 20 56 6F 72 74 65 69 6C 21
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.429 Beiträge
 
Delphi 10.4 Sydney
 
#10

AW: Dynamisches Array in DLL kann nicht erweitert werden

  Alt 6. Mär 2017, 22:13
Damit hast du den Fehler nicht beseitigt, nur das Symptom Zugriffsverletzung tritt zufällig an dieser Stelle nicht mehr auf. Wenn Speichermanager A Speicher freigibt, den Speichermanager B reserviert hat, wird Speichermanager B irgendwann versuchen darauf zuzugreifen. Das kann in einem völlig anderen Programmteil irgendwann wieder zur Zugriffsverletzung führen und du wirst nicht wissen warum.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:45 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz