![]() |
Variant + varStrArg = was ist das?
also wenn ich in den Delphi-Sourcn such, dann finde ich da kaum etwas zu diesem Typen (eigentlich garnichts, abgesehn von der Definition)
const varStrArg = $0048; { vt_clsid } Laut MSDN und Co. ist $48 / vt_clsid eine CLSID, also wäre in Delphi TGUID allerdings, wenn ich dann mal im INet such, dann fand ich in Google eigentlich nichts Brauchbares (auf Delphi bezogen) und die Suche in der DP war auch nicht wirklich ergiebig, aber wenn, dann war da plötzlich die Rede von einem OLE-kompatiblem String :shock: Was ist denn nun? Benötigt würde es für die Serialisierung in ![]() Und im Moment bin ich wirklich schon so weit, daß ich dieses wohl einfach ignorieren werde :oops: |
Re: Variant + varStrArg = was ist das?
*push*
![]() |
Re: Variant + varStrArg = was ist das?
|
Re: Variant + varStrArg = was ist das?
ja, das Steht in Google und auch im MSDN ... nur ist es in Delphi keine GUID.
Ein published Property vom Typ TGUID wird garnicht erst in der RTTI enthalten ... es wird sozusagen beim Auslesen der published Properties einfach übergangen/ignoriert. Wenn man mal in der DP danach sucht, dann kommt man auf einen "OLE-kompatiblem String", was auch immer das sein mag :shock: (ein OLE-String aka WideString ist es schonmal nicht, denn der hat einen anderen Wert) Und ansonsten brachte die Suche danach, in Bezug auf Delphi und wie dieses es handhabt, keinerlei Erleuchtung, da dieses praktisch nirgendwo verwendet wird. PS: varStrArg klingt auch nicht grade nach GUID bzw. CLSID :stupid: |
Re: Variant + varStrArg = was ist das?
varStrArg wird nur Delphi-intern verwendet und nie zu COM durchgereicht. Das erklärt sich so: Delphi erlaubt es, an einem Variant eine Methode aufzurufen. Dann wird die Routine Variants.@DispInvoke aufgerufen, die den Aufruf entweder an einen registrierten "Custom Variant Type" weiterleitet - falls der Variant von diesem Typen ist - oder den Prozedurzeiger VarDispProc aufruft, falls es sich um ein Dispatchinterface handelt. Diese Routinen brauchen dabei natürlich neben den Parametern auch noch weitere Informationen für den Aufruf, insbesondere welche und wie viele Parameter es überhaupt gibt. Diese Informationen werden in Form eines System.TCallDesc-Records übergeben. Und genau dort liegt der Hase im Pfeffer: Wenn im Aufruf Ansistrings oder Stringliterale übergeben wurden, ist dort als Typ varStrArg eingetragen. Falls der Aufruf an ein Dispatchinterface geht und ComObj eingebunden ist (diese Unit stellt eine Implementierung für VarDispProc bereit), werden die Parameter in einen BSTR umgewandelt, da COM mit varStrArg natürlich nichts anfangen kann.
|
Re: Variant + varStrArg = was ist das?
Also kann ich das weiterhin einfach so ignorieren?
Ich hab praktisch noch nie so richtig mit Variants gearbeitet und versuch das quasi jetzt so hinzubekommen (bin über die Delphi-Sourcen und die Suche via DP/Google jetzt schon so weit gekommen) Aktuell hab ich das Speichern von Variants so:
Delphi-Quellcode:
tkVariant: Begin
V := GetVariantProp(C, String(List[i].Name)); Case TVarData(V).VType of varEmpty, varNull: SavePropInfos(nil, List[i]); varShortInt: Begin Node := AddNode(List[i].Name); SavePropInfos(Node, List[i]); Node.Attributes['variant'] := 'ShortInt'; Node.Data := IntToStr(TVarData(V).VShortInt); End; varSmallInt: Begin Node := AddNode(List[i].Name); SavePropInfos(Node, List[i]); Node.Attributes['variant'] := 'SmallInt'; Node.Data := IntToStr(TVarData(V).VSmallInt); End; varInteger: Begin Node := AddNode(List[i].Name); SavePropInfos(Node, List[i]); Node.Attributes['variant'] := 'Integer'; Node.Data := IntToStr(TVarData(V).VInteger); End; varError: Begin Node := AddNode(List[i].Name); SavePropInfos(Node, List[i]); Node.Attributes['variant'] := 'HRESULT'; Node.Data := IntToStr(TVarData(V).VError); End; varInt64: Begin Node := AddNode(List[i].Name); SavePropInfos(Node, List[i]); Node.Attributes['variant'] := 'Int64'; Node.Data := IntToStr(TVarData(V).VInt64); End; varByte: Begin Node := AddNode(List[i].Name); SavePropInfos(Node, List[i]); Node.Attributes['variant'] := 'Byte'; Node.Data := IntToStr(TVarData(V).VByte); End; varWord: Begin Node := AddNode(List[i].Name); SavePropInfos(Node, List[i]); Node.Attributes['variant'] := 'Word'; Node.Data := IntToStr(TVarData(V).VWord); End; varLongWord: Begin Node := AddNode(List[i].Name); SavePropInfos(Node, List[i]); Node.Attributes['variant'] := 'LongWord'; Node.Data := IntToStr(TVarData(V).VLongWord); End; {$IF Declared(varUInt64)} varUInt64: Begin Node := AddNode(List[i].Name); SavePropInfos(Node, List[i]); Node.Attributes['variant'] := 'UInt64'; If Int64(TVarData(V).VUInt64) < 0 Then Node.Data := '$' + IntToHex(Int64(TVarData(V).VUInt64), 16) Else Node.Data := IntToStr(Int64(TVarData(V).VUInt64)); End; {$IFEND} varSingle: Begin Node := AddNode(List[i].Name); SavePropInfos(Node, List[i]); Node.Attributes['variant'] := 'Single'; Node.Data := FloatToStr(TVarData(V).VSingle); End; varDouble: Begin Node := AddNode(List[i].Name); SavePropInfos(Node, List[i]); Node.Attributes['variant'] := 'Double'; Node.Data := FloatToStr(TVarData(V).VDouble); End; varCurrency: Begin Node := AddNode(List[i].Name); SavePropInfos(Node, List[i]); Node.Attributes['variant'] := 'Currency'; Node.Data := CurrToStr(TVarData(V).VCurrency); End; varDate: Begin Node := AddNode(List[i].Name); SavePropInfos(Node, List[i]); Node.Attributes['variant'] := 'DateTime'; Node.Data := DateTimeToStr(TVarData(V).VDate); End; varBoolean: Begin Node := AddNode(List[i].Name); SavePropInfos(Node, List[i]); Node.Attributes['variant'] := 'Boolean'; Node.Data := BooleanIdents[TVarData(V).VBoolean]; End; varOleStr: Begin Node := AddNode(List[i].Name); SavePropInfos(Node, List[i]); Node.Attributes['variant'] := 'OLEStr'; Node.Data := WideString(Pointer(TVarData(V).VOleStr)); End; varString: Begin Node := AddNode(List[i].Name); SavePropInfos(Node, List[i]); Node.Attributes['variant'] := 'AnsiString'; Node.Data := AnsiString(TVarData(V).VString); End; {$IF Declared(UnicodeString)} varUString: Begin Node := AddNode(List[i].Name); SavePropInfos(Node, List[i]); Node.Attributes['variant'] := 'WideString'; Node.Data := UnicodeString(TVarData(V).VUString); End; {$IFEND} {varStrArg: Begin Node := AddNode(List[i].Name); SavePropInfos(Node, List[i]); Node.Attributes['variant'] := 'OLEStr'; Node.Data := TVarData(V).vt_clsid End;} Else CheckUsupported(List[i]); End; End; |
Re: Variant + varStrArg = was ist das?
Bei Variants selbst kommt varStrArg nie als Typencode vor, das stimmt.
Ich weiß nicht, was genau du machen willst, aber mir erscheint deine Technik zu kompliziert. Eigentlich musst du doch nur unterscheiden zwischen zwei Fällen: Finalisierungsbedürftigen Variants und reinen Datenvariants. Die Datenvariants, z.B. alle Arten von Zahlen, Boolean und HResult, kannst du einfach direkt speichern. Falls dir die 16 Byte zu viel sind, kannst du mit dem Array VarUtils.CVarTypeToElementInfo die Größe der Daten heraussuchen, die du tatsächlich speichern musst. Bei den anderen Variants musst du die Fälle einzeln abgrasen, aber es sind nicht sehr viele. |
Re: Variant + varStrArg = was ist das?
Das ist Teil der Serialisierung meiner XML-Klasse.
Also der Inhalt wird praktisch in Text umgewandelt. Und zum Wiederherstellen des Variants wird noch ein Attribut mit dem Typ der Daten im Variant mitgepseichert. Der Inhalt steht dann quasi in einer leicht "menschlich" lesbaren Form in der XML-Datei, also nicht binär. |
Re: Variant + varStrArg = was ist das?
Ist der Witz von Variants nicht gerade, dass es keinen festen Datentyp gibt?
|
Re: Variant + varStrArg = was ist das?
Ja, in einem Vairant können verschiedene "feste" Typen drin sein,
drum "muß" ich ihn dann in den gerade in seinem Inneren liegenden Typen zerlegen, da ich ihn nicht Binär speichern will. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:28 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-2025 by Thomas Breitkreuz