AGB  ·  Datenschutz  ·  Impressum  







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

Typinformation von Records

Ein Thema von jensw_2000 · begonnen am 25. Sep 2007 · letzter Beitrag vom 25. Sep 2007
Antwort Antwort
jensw_2000
(Gast)

n/a Beiträge
 
#1

Typinformation von Records

  Alt 25. Sep 2007, 13:28
Ich habe hier (klick) eine Unit von Sirius gefunden, mit der man dynamische Strukturen komfortabel in einen Stream packen kann.
Bleibt das Problem, das TypeInfo(TMyRecord) nur funktioniert, wenn der Record einen Member vom Typ Variant hat.

Beispiel:

Delphi-Quellcode:
Type
  TMyRecord1 = packed Record
    aInteger : integer;
    aString : String[100];
  end;

...

Typeinfo(TMyRecord1) >>>> Der Typ TMyRecord1 enthält keine TypInformation.
Delphi-Quellcode:
Type
  TMyRecord2 = packed Record
    Dummy : variant;
    aInteger : integer;
    aString : String[100];
  end;

Typeinfo(TMyRecord2) >>>> geht
Warum ist das so ?
Kann ich irgendwie an die Typinformation kommen ohne einen Variant in den Record zu stecken ?

Der Record wird als Parameter zum Aufruf einer DLL Prozedur verwendet. Die DLL verwendet kein Sharemem. Daher habe ich etwas Respekt vor dem Variant, weil der der geneigte "DLL Benutzer" versuchen könnte, lange Strings über den Variant zu transportieren.



Schöne Grüße,
Jens
  Mit Zitat antworten Zitat
Sidorion

Registriert seit: 23. Jun 2005
403 Beiträge
 
#2

Re: Typinformation von Records

  Alt 25. Sep 2007, 14:35
Hättest Du mal die OH für die Fehlermeldung gelesen, wüsstest Du, dass Records keine Typinformationen bereitstellen. Versuch mal, den Schalter M (TYPEINFO) anzuschalten, also:
Delphi-Quellcode:
{M+}
   TMyRecord1 = packed Record
    aInteger : integer;
    aString : String[100];
  end;
{M-}
Wenn das nicht klappt (wovon ich ausgehe, da Records keine published, sondern public Member haben), empfehle ich, den Record als Puffer und die Länge des Typs (sizeof) zu übergeben.
Manchmal sehen Dinge, die wie Dinge aussehen wollen mehr wie Dinge aus, als Dinge
<Esmerelda Wetterwachs>
  Mit Zitat antworten Zitat
jensw_2000
(Gast)

n/a Beiträge
 
#3

Re: Typinformation von Records

  Alt 25. Sep 2007, 15:22
Die Hilfe zu dem Fehler habe ich schon gelesen. Hätte mich auch fast damit zufrieden gegeben, aber es gibt hier in der DP einige Beiträge (z.B. hier), in denen Typeinfo(TEinRecord) offensichtlich funktioniert.
Generell geht es bei mir ja auch, sobald ich einen "Dummy"-Member" von Typ Variant mit in den Record lege.
Und genau das würde ich gerne verstehen.
Warum geht es "nur" mit mindestens einem Variant-Member, bzw. wie kann ich diesen Effekt auch ohne Variant-Member erreichen ?

PS: Die Compiler-Direktiven {M+} {M-} helfen nicht ....
  Mit Zitat antworten Zitat
Hawkeye219

Registriert seit: 18. Feb 2006
Ort: Stolberg
2.227 Beiträge
 
Delphi 2010 Professional
 
#4

Re: Typinformation von Records

  Alt 25. Sep 2007, 15:38
Hallo Jens,

der Compiler generiert (eingeschränkte) Typinformationen für Records immer dann, wenn der Record Elemente enthält, die finalisiert werden müssen (z.B. Variants, dynamische Strings oder Arrays).

Zitat:
[...]aber es gibt hier in der DP einige Beiträge (z.B. hier), in denen Typeinfo(TEinRecord) offensichtlich funktioniert.
Nicht offensichtlich, nur scheinbar...

Gruß Hawkeye
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#5

Re: Typinformation von Records

  Alt 25. Sep 2007, 15:47
Der Grund ist, das referenzgezählte Typen aufgeräumt werden müssen. Beispiel: Ich habe eine lokale Variable als Record deklariert, der ein IInterface-Feld besitzt. Wenn ich diesem Feld etwas zuweise, greift die Referenzzählung. Wenn ich die Routine verlasse, muss der Referenzzähler dekrementiert werden. Dies wird erledigt, indem auf die Typinformation zugegriffen wird. Wenn jedoch kein Feld, welches aufgeräumt werden muss, im Record enthalten ist, dann wird die Typinformation intern nicht benötigt.
Referenzgezählte Typen sind dynamische Arrays, Interfaces und Ansistrings. Bei Varianten bin ich mir ehrlich gesagt nicht ganz sicher, ich habe mich mit ihnen nie näher auseinandergesetzt.
Wenn du keine Lösung finden solltest, dann nimm lieber einen der oben genannten Typen, diese sind nur 4 Byte, statt 16 Bytes bei Variants, groß.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
jensw_2000
(Gast)

n/a Beiträge
 
#6

Re: Typinformation von Records

  Alt 25. Sep 2007, 16:03
Danke, das bringt Licht ins Dunkel.

Mal schauen ob ich dann lieber eine Klasse verwende oder den Record einfach "blind" mit MyRecord,sizeof(TMyRecord) speichere.

@Hawkeye219
Bedeutet "eingeschränkte Typinformationen", dass die Typeinformation nur Informationen über die zu finalisierenden Member enthält?
  Mit Zitat antworten Zitat
Hawkeye219

Registriert seit: 18. Feb 2006
Ort: Stolberg
2.227 Beiträge
 
Delphi 2010 Professional
 
#7

Re: Typinformation von Records

  Alt 25. Sep 2007, 16:32
Den genauen Aufbau der Strukturen kenne ich leider nicht. Nach meinem Wissen enthalten sie nur die wirklich notwendigen Daten (Record-Größe, Informationen über die zu intialisierenden/finalisierenden Felder), aber keine Feldnamen oder Typinformationen für die übrigen Felder.

Vielleicht kein negaH noch etwas beisteuern, ansonsten schaue mal bei Hallvard Vassbotn vorbei.

Gruß Hawkeye
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#8

Re: Typinformation von Records

  Alt 25. Sep 2007, 17:06
Wenn man Assembler kann, dann sieht man in der automatisch aufgerufenen Routine FinalizeRecord sehr deutlich den Aufbau. Hier meine Umsetzung:
Delphi-Quellcode:
type
TFinalField = packed record
  Typ: PPTypeInfo; //Beachte den Zeiger auf den Zeiger!
  Offset: integer;
end;

TRecordTypeData = packed record
  RecSize: integer;
  FinalFieldCount: integer;
  FinalFields: array[0..MaxWord div sizeof(TFinalField)-1] of TFinalField;
  //Eigentlich:
  //FinalFields: array[0..FinalFieldCount-1] of TFinalField;
end;

procedure dumpRecTypeData(p: PTypeData);
var i: integer;
begin
writeln('Size: ', PInteger(p)^);
writeln('Number of fields to finalize: ', PInteger(Integer(p)+4)^);
for i:=1 to PInteger(Integer(p)+4)^ do
 begin
  writeln;
  writeln('Offset: ', PInteger(integer(p)+12)^);
  writeln('PTypeInfo: ', inttohex(PInteger(PPointer(integer(p)+8))^, 8));
  inc(integer(p), 8);
 end;
end;
Es werden also wirklich nur die Felder gespeichert, die finalisiert werden müssen.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  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 09:02 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