Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Variant + varStrArg = was ist das? (https://www.delphipraxis.net/132293-variant-varstrarg-%3D-ist-das.html)

himitsu 9. Apr 2009 09:30


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 Hier im Forum suchenhimXML.
Und im Moment bin ich wirklich schon so weit, daß ich dieses wohl einfach ignorieren werde :oops:

himitsu 19. Apr 2009 14:14

Re: Variant + varStrArg = was ist das?
 
*push* http://fnse.de/S02/15S.gif

Alter Mann 19. Apr 2009 14:38

Re: Variant + varStrArg = was ist das?
 
VT_CLSID 72 puuid Pointer to a CLSID (or other GUID).

Nachlesbar hier.

1 sek. Google

himitsu 19. Apr 2009 14:44

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:

Apollonius 19. Apr 2009 15:13

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.

himitsu 19. Apr 2009 15:37

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;

Apollonius 19. Apr 2009 15:56

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.

himitsu 19. Apr 2009 16:16

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.

Namenloser 19. Apr 2009 17:35

Re: Variant + varStrArg = was ist das?
 
Ist der Witz von Variants nicht gerade, dass es keinen festen Datentyp gibt?

himitsu 19. Apr 2009 17:53

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 05:34 Uhr.
Seite 1 von 2  1 2      

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