AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Probleme mit Tdictionary in Packages

Ein Thema von kompi · begonnen am 3. Feb 2017 · letzter Beitrag vom 6. Feb 2017
Antwort Antwort
kompi

Registriert seit: 27. Apr 2012
Ort: Duisburg
54 Beiträge
 
Delphi 11 Alexandria
 
#1

Probleme mit Tdictionary in Packages

  Alt 3. Feb 2017, 16:58
Hallo DP'ler,

ich habe Probleme beim Aufruf von Tdictionary in Packages. Folgendes habe ich gemacht

1. Deklaration eines Typen in einer extra unit
Delphi-Quellcode:
   Tdokutype = class(Tdictionary<Integer ,Tdokurec>);
   Tdokurec = record
                                Filename : string;
                                Description : string;
                                Version : string;
                                Dokutyp : string;
                                Datum : string;
                                EngType : string;
                                Ausgeliefert : string;
                                ConNo : string;
                                ConTo : string;
                              end;
2. Definitionen von diversen Objekten in einer extra unit:

Delphi-Quellcode:
   Tbasicnode = class(TPersistent)
       published
   
        Property Dokumente : Tdokutype read fdokument write fdokument;

end;
Die Definition von Tbasicnode ist hier nur verkürzt wiedergegeben.

Diese beiden units sind in einem Package ausgelagert. Dieses Package wird statisch in das Hauptprogramm eingebunden.

Die Objekte vom Typ Tbasicnode werden im Hauptprogramm an Nodes eines Virtualstringtrees angebunden. Das funktioniert auch alles hervorragend.

Jetzt zu meinem Problem.

In einem weiteren Package, welches diesmal dynamisch eingebunden wird, greife ich folgendermaßen auf obiges Tdictionary zu.

Delphi-Quellcode:
procedure Taml.savedoctoaml(const axmlnode: IXMLNode; adatanode: Tbasicnode; apropname : string);
var
  propvalue : Tdokutype;
  key : integer;
  r : Tdokurec;
  xmlnode : Ixmlnode;
  subnode : Ixmlnode;
  subsubnode : Ixmlnode;
  subsubsubnode : Ixmlnode;
begin
  if not (getobjectprop(adatanode, apropname) is Tdokutype) then
    exit;
  try
    propvalue := getobjectprop(adatanode, apropname) as Tdokutype;
  except
    exit;
  end;
  if propvalue.Count = 0 then
    exit;
  try
    for key in propvalue.keys do
    begin
      if propvalue.TryGetValue(key,r) then
      begin
        try
          xmlnode := axmlnode.AddChild('InternalElement');
          xmlnode.Attributes['Name'] := r.Description;
          xmlnode.Attributes['ID'] := r.ConNo;
          subnode := xmlnode.addchild('Attribute');
          subnode.attributes['Name'] := 'aml-DocLang';
          subnode.Attributes['AttributeDataType'] := 'xs:string';
          subsubnode := subnode.AddChild('Value');
          subsubnode.NodeValue := 'de-DE';
          subnode := xmlnode.AddChild('ExternalInterface');
          subnode.Attributes['Name'] := 'Document';
          subnode.Attributes['RefBaseClassPath'] := 'AutomationMLBPRInterfaceClassLib/ExternalDataReference';
          subnode.Attributes['ID'] := r.ConNo;
          subsubnode := subnode.AddChild('Attribute');
          with subsubnode do begin
            Attributes['Name'] := 'MiMeType';
            Attributes['AttributeDataType'] := 'xs:string';
            subsubsubnode := addchild('Value');
            subsubsubnode.NodeValue := setmimetype(extractfileext(r.Filename));
          end;
          subsubnode := subnode.AddChild('Attribute');
          with subsubnode do begin
            Attributes['Name'] := 'refURI';
            Attributes['AttributeDataType'] := 'xs:string';
            subsubsubnode := addchild('Value');
            subsubsubnode.NodeValue := extractfilename(r.Filename);
          end;
        finally
          xmlnode := nil;
          subnode := nil;
          subsubnode := nil;
          subsubsubnode := nil;
        end;
      end;
    end;
  finally
// propvalue := nil;
  end;
end;
Das funktioniert auch alles, jedoch bekomme ich beim Beenden des Hauptprogramms (obiges Package ist bereits vorher entladen), einen Zugriffsfehler bei der Freigabe des Tdictionary Objekts. Dieser Zugriffsfehler tritt nur dann auf, wenn durch die Keys iteriert wird.

Binde ich jedoch die unit direkt in das Hauptprogramm ein, ist alles in Ordnung.

Weiss jemand von Euch einen Rat?

Gruß Kompi
Detlef Schmitz
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
3.908 Beiträge
 
Delphi 12 Athens
 
#2

AW: Probleme mit Tdictionary in Packages

  Alt 4. Feb 2017, 07:50
Vielleicht weil du
propvalue := nil; // Ist das die Stelle wo es kracht ?
setzt ?

Wenn ich das Richtig sehe ist propvalue aber kein Interface.

Was passiert bei propvalue.Free; ?

Keine Ahnung was dein getobjectprop macht, aber du solltest mal checken wer erzeugt und wer freigeben muss.

Rollo
  Mit Zitat antworten Zitat
kompi

Registriert seit: 27. Apr 2012
Ort: Duisburg
54 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Probleme mit Tdictionary in Packages

  Alt 4. Feb 2017, 09:27
@Rollo62

Danke für Deine Antwort.

Die Zeile propvalue := nil ist auskommentiert, so dass dies nie aufgerufen wird. Ich hatte dies aufgrund eines Versuchs noch drin gelassen.

Die function getobjectprop ist eine Delphi eigene Funktion aus dem RTTI System. Sie gibt eine als published definierte Eigenschaft eines Objekts zurück, das wiederum ein Objekt ist. Dies ist ja hier der Fall, da Tdokutype = class(Tdictionary<...>) ist.

Die Eigenschaft Dokumente in Tbasicnode hat einen Getter und Setter Fdokumente. Fdokumente ist wiederum vom Typ Tdokutype;

Im constructor von Tbasicnode wird mittels fdokumente := Tdokutype.create das Objekt erzeugt, und im destructor von Tbasicnode das Objekt mittels fdokumente.free wieder freigegeben.
Dies passiert alles im Hauptprogramm.

Ansonsten wird das Objekt an keiner anderen Stelle freigegeben.

Und genau im Destruktor bei der Freigabe von Fdokumente kracht es,wenn ich die Unit mit der Methode savedoctoaml in ein dynamisch ladbares Package auslagere. Binde ich diese Unit jedoch direkt in das Hauptprogramm ein, so funktioniert alles bestens.

Das ganze soll im übrigen ein Writer für AutomationML werden.

Gruß Kompi
Detlef Schmitz
  Mit Zitat antworten Zitat
kompi

Registriert seit: 27. Apr 2012
Ort: Duisburg
54 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Probleme mit Tdictionary in Packages

  Alt 6. Feb 2017, 08:26
Ich habe jetzt weiter geforscht.

Beim Einbinden der unit (die savedoctoaml enthält) in das Hauptprogramm gibt der Aufruf von propvalue.keys gleich ein Keycollection-Objekt zurück, da ja Einträge vorhanden sind.

Binde ich jedoch diese Unit in ein dynamisch ladbares Package ein, so wird beim Aufruf von propvalue.keys ein neues Keycollection-Objekt erzeugt und auch im Dictionary gespeichert. Beim Entladen des Packages zeigt das neue Keycollection-Objekt jedoch ins Nirwana. Deshalb kommt es beim Freigeben des Tdictionary zu einem Laufzeitfehler.

Ich habe noch keine Ahnung, wie man hier einen Workaround machen kann. Vielleicht wisst ihr ja eine Möglichkeit.

Gruß Kompi
Detlef Schmitz
  Mit Zitat antworten Zitat
Antwort Antwort

 

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 06:22 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