Autor Téma: implementace boost::any v Delphi  (Přečteno 223 krát)

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2295
  • Karma: 123
    • Verze Delphi: D2007, XE3, DX10
implementace boost::any v Delphi
« kdy: 05-11-2018, 10:55:19 »
Portuju komunikacni protokol do Delphi a narazil jsem na problem s implementaci boost::any, coz je v C++ nahrada za object. Protoze v Java/C# je vsechno objekt, tak to reprezentuji jako:
Kód: C [Vybrat]
  1. public class BoostAny {
  2.   private EBoostAnyType _Type;
  3.   private object _Value;
  4.   ...
  5. }
coz neni problem udelat v Delphi stejne:
Kód: Delphi [Vybrat]
  1. TBoostAny = class
  2. strict private
  3.   FType: EBoostAnyType;
  4.   FValue: TObject;
  5.   ...
  6. end;

Ovsem problem bude se serializaci/deserializaci jednoduchych typu napr. integer aj., ktere nejsou potomky TObject, takze nezbyde zrejme nez ty jednoduche typy nejak zaboxovat :-(

Nedelal jste nekdo neco podobneho, ze byste se podelil o know-how?

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 1285
  • Karma: 56
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:implementace boost::any v Delphi
« Odpověď #1 kdy: 05-11-2018, 11:02:10 »
Excellent
Rated 1 time
Nedelal jste nekdo neco podobneho, ze byste se podelil o know-how?

Ne, ale nejblize je TValue (chapu ze nepokryje vsechny moznosti, jako napr. strukturu typu record; to by byl snad jen genericky TBoostAny<T>).
« Poslední změna: 05-11-2018, 11:06:14 od Delfin »
I'm a soldier, so don't panic! I know the underground! I like WTFPL license! No more Google, go duck, go!

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2295
  • Karma: 123
    • Verze Delphi: D2007, XE3, DX10
Re:implementace boost::any v Delphi
« Odpověď #2 kdy: 05-11-2018, 11:42:58 »
Ne, ale nejblize je TValue (chapu ze nepokryje vsechny moznosti, jako napr. strukturu typu record; to by byl snad jen genericky TBoostAny<T>).
Na prvni pohled se zda, ze to TValue je dobrej napad a melo by s tim jit implementovat vsechno, co potrebuju. Asi lepsi nez variant, o kterem jsem puvodne uvazoval.

Offline Ondřej Pokorný

  • Guru
  • *****
  • Příspěvků: 786
  • Karma: 56
    • Verze Delphi: Primárně Lazarus, jinak D7 až aktuální
    • Kluug.net
Re:implementace boost::any v Delphi
« Odpověď #3 kdy: 05-11-2018, 13:32:20 »
nejblize je TValue (chapu ze nepokryje vsechny moznosti, jako napr. strukturu typu record; to by byl snad jen genericky TBoostAny<T>).

Co já vím tak pokryje - alespoň já recordy do TValue deserializuju.
Embarcadero Technology Partner, juj. Člen Lazarus týmu, oj.

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 1285
  • Karma: 56
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:implementace boost::any v Delphi
« Odpověď #4 kdy: 05-11-2018, 13:35:03 »
Co já vím tak pokryje - alespoň já recordy do TValue serializuju.

Mohl bych poprosit ukazku? Recordy nemaji typove informace, tudiz bych rekl, ze neco ve stylu MyValue.From<TMyRecord>(MyRecord) neuchova zaznam...
« Poslední změna: 05-11-2018, 13:51:17 od Delfin »
I'm a soldier, so don't panic! I know the underground! I like WTFPL license! No more Google, go duck, go!

Offline Ondřej Pokorný

  • Guru
  • *****
  • Příspěvků: 786
  • Karma: 56
    • Verze Delphi: Primárně Lazarus, jinak D7 až aktuální
    • Kluug.net
Re:implementace boost::any v Delphi
« Odpověď #5 kdy: 05-11-2018, 13:40:44 »
Co já vím tak pokryje - alespoň já recordy do TValue serializuju.

Mohl bych poprosit ukazku? Recordy nemaji typove informace, tudiz bych rekl ze neco ve stylu MyValue.From<TMyRecord>(MyRecord) zaznam neuchova.

Mám to v rámci OXml: http://www.kluug.net/oxml.php

Tady je relevantní kód pro vytvoření nové TValue ze všeho možného:
Kód: Delphi [Vybrat]
  1. function TXMLRTTIDeserializer.CreateNewValue(const aType: TRttiType;
  2.   aXMLTagName: string; const aItemNode: PXMLNode;
  3.   var outAllocatedData: Pointer): TValue;
  4. begin
  5.   aXMLTagName := OXmlXMLToName(aXMLTagName);
  6.   outAllocatedData := nil;
  7.  
  8.   case aType.TypeKind of
  9.     tkInteger: Result := TValue.From<Integer>(0);
  10.     tkInt64: Result := TValue.From<Int64>(0);
  11.     tkChar: Result := TValue.From<Char>(#0);
  12.     tkWChar: Result := TValue.From<WideChar>(#0);
  13.     tkFloat: Result := TValue.From<Double>(0);
  14.     tkString: Result := TValue.From<string>('');
  15.     tkWString: Result := TValue.From<WideString>('');
  16.     tkLString: Result := TValue.From<AnsiString>('');
  17.     tkUString: Result := TValue.From<UnicodeString>('');
  18.     tkClass: Result := CreateObject(aXMLTagName, aType as TRttiInstanceType);
  19.     tkInterface: Result := CreateObject(aXMLTagName, nil);
  20.     tkRecord:
  21.     begin
  22.       outAllocatedData := AllocMem(aType.TypeSize);
  23.       TValue.Make(outAllocatedData, aType.Handle, Result);
  24.       CheckRecordForCreateClasses(Result.GetReferenceToRawData, aType, aItemNode);
  25.     end;
  26.   else
  27.     //error reading
  28.     raise EXMLRTTIDeserializer.CreateFmt(OXmlLng_DeserializerNotSupportedListItemType, [aType.Name]);
  29.   end;
  30. end;
  31.  

Pro record použiješ TValue.Make() s velikostí recordu.

Nějak nerozumím tvému "Recordy nemaji typove informace".
Embarcadero Technology Partner, juj. Člen Lazarus týmu, oj.

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 1285
  • Karma: 56
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:implementace boost::any v Delphi
« Odpověď #6 kdy: 05-11-2018, 13:51:02 »
Nějak nerozumím tvému "Recordy nemaji typove informace".

To jsem napsal nesmysl. Beru zpet. Dik za ukazku (byt primo neodpovedela na to co jsem mel na mysli)... Nicmene TValue tedy muze byt pouzit i pro struktury typu record. Stejne jako pro ostatni typy se da record zkopirovat pomoci TValue.From<TMyRecord>(MyRecord).
« Poslední změna: 05-11-2018, 14:01:35 od Delfin »
I'm a soldier, so don't panic! I know the underground! I like WTFPL license! No more Google, go duck, go!

 

S rychlou odpovědí můžete používat BB kódy a emotikony jako v běžném okně pro odpověď, ale daleko rychleji.

Jméno: E-mail:
Ověření:
Datový typ v Delphi, který má True a False: