Modifications

Aller à : navigation, rechercher

Delphi RTTI et C++Builder

7 502 octets ajoutés, 18 mars 2016 à 09:11
Updated with WM. LOC-21071
{{Parent|Utilisation des informations RTTI - Index|Utilisation des informations RTTI}}

==Découverte du type à l'exécution (réflexion)==

===Désambiguïsation===

Les informations RTTI de {{Delphi}} sont différentes des informations RTTI standard de C++ :

* Les informations RTTI de {{Delphi}} vous permettent d'explorer les champs, les méthodes d'une classe, et ainsi de suite.
* Les informations RTTI de C++ vous permettent d'identifier le type d'une variable et de comparer l'égalité des types, ou l'ordre de tri.

<blockquote>'''Remarque&nbsp;:''' L'option <span style="color: #598527">'''Projet &gt; Options &gt; [[Compilateur C++|Compilateur C++]] &gt; Activer RTTI'''</span> du compilateur se réfère aux informations RTTI standard de C++.</blockquote>

===Génération des informations RTTI===

Seules les classes de style {{Delphi}} peuvent avoir des informations de style {{Delphi}} dans C++ (voir [[Declspec(delphiclass)|__declspec(delphiclass)]]).

Des informations RTTI peuvent être générées pour tout type de membre de classe (méthodes, champs, propriétés) avec toute visibilité (__published, public, protected, private). Pour contrôler la génération des informations RTTI, les spécifications suivantes peuvent être utilisées&nbsp;:

* [[Pragma explicit rtti|#pragma explicit_rtti]] (c'est l'équivalent C++ de [[Directive RTTI (Delphi)|<nowiki>{$RTTI}</nowiki>]])
* [[Declspec(delphirtti)|__declspec(delphirtti)]] (c'est l'équivalent C++ de [[Informations de type à l'exécution (Delphi)|<nowiki>{$M}/{$TYPEINFO}</nowiki>]])
* [[Published|__published]]

'''Exemple&nbsp;:'''
<source lang="cpp">
#include <System.hpp>
#include <Rtti.hpp>
#include <tchar.h>
#include <stdio.h>

// Enable RTTI generation for private fields
#pragma explicit_rtti fields(private)

class __declspec(delphiclass) TBuffer {
private:
int wrHead, rdHead;

// ...
public:
TBuffer() {

}
};

// ---------------------------------------------------------------------------

int _tmain(int argc, _TCHAR* argv[]) {
TRttiContext context;

// Get class RTTI
TRttiInstanceType *cls = dynamic_cast<TRttiInstanceType*>
(context.GetType(__delphirtti(TBuffer)));

if (cls) {
// Get field RTTI
TRttiField *field = cls->GetField("wrHead");
if (field) {
printf("%ls", field->ToString().c_str());
}
else {
puts("\"wrHead\" doesn't have RTTI");
}
}
else {
puts("\"TBuffer\" doesn't have RTTI");
}

return 0;
}
</source>

'''Sortie console&nbsp;:'''

wrHead: int @ 00

Dans cet exemple, les informations RTTI de classe sont extraites à l'aide de la fonction [[Delphirtti|__delphirtti]] (qui renvoie un pointeur sur une variable [[lib_fr:System.TypInfo.TTypeInfo|TTypeInfo]]). Il est possible de faire la même chose avec l'opérateur [[Classid|__classid]]. Voir le code suivant<source lang="cpp">
TRttiInstanceType *cls = dynamic_cast<TRttiInstanceType*>
(context.GetType(__classid(TBuffer)));
</source>

<blockquote>
'''Remarque&nbsp;:''' Les informations RTTI extraites avec [[Delphirtti|__delphirtti]] peuvent différer selon les plates-formes. Par exemple, sur iOS et OSX, la fonction [[Delphirtti|__delphirtti]] d'un caractère [[Char16 t|char16_t]] renvoie une variable [[lib_fr:System.TypInfo.PTypeInfo|PTypeInfo]] qui correspond aux informations RTTI de {{Delphi}} pour le type [[lib_fr:System.WideChar|WideChar]] de {{Delphi}}.
</blockquote>

Sur la plate-forme Windows, la fonction [[Delphirtti|__delphirtti]] d'un caractère [[Wchar t|wchar_t]] renvoie une variable [[lib_fr:System.TypInfo.PTypeInfo|PTypeInfo]] qui correspond aux informations RTTI de {{Delphi}} pour le type [[lib_fr:System.WideChar|WideChar]] de {{Delphi}}.

Cette fonctionnalité est illustrée dans l'exemple de code suivant&nbsp;:

<source lang="cpp">
#include <stdio.h>

static System::UTF8String getTypeInfoName(System::Typinfo::PTypeInfo ti)
{
#ifndef _DELPHI_NEXTGEN
return System::UTF8String(ti->Name);
#else
int len = ti->Name;
const char* p = reinterpret_cast<char*>(&(ti->Name));
return System::UTF8String(p+1, len);
#endif
}

int main()
{
System::Typinfo::PTypeInfo pti;
pti = __delphirtti(char16_t);
printf("Kind=%d, Name='%s'\n", pti->Kind, getTypeInfoName(pti).c_str());
pti = __delphirtti(wchar_t);
printf("Kind=%d, Name='%s'\n", pti->Kind, getTypeInfoName(pti).c_str());
return 0;
}
</source>

'''Sortie&nbsp;:'''

{| border="1" frame="hsides" rules="rows"
|-
! '''Plate-forme'''
! '''Sortie'''
|-
| style="text-align: left; vertical-align: top;" |
WIN64
| style="text-align: left; vertical-align: top;" |
Kind=1, Name='char16_t'

Kind=9, Name='Char'
|-
| style="text-align: left; vertical-align: top;" |
iOS
| style="text-align: left; vertical-align: top;" |
Kind=9, Name='Char'

Kind=9, Name='wchar_t'
|}

===Enracinement du type===

Vous ne pouvez pas utiliser les méthodes [[lib_fr:System.Rtti.TRttiContext.FindType|FindType]] et [[lib_fr:System.Rtti.TRttiContext.GetTypes|GetTypes]] pour obtenir les informations RTTI de {{Delphi}} pour des classes définies en langage C++. La raison est que [[lib_fr:System.Rtti.TRttiContext.FindType|FindType]] et [[lib_fr:System.Rtti.TRttiContext.GetTypes|GetTypes]] effectuent des recherches dans les packages d'exécution, et que le lieur C++ n'effectue aucun enracinement de type.

D'autre part, le lieur {{Delphi}} enracine les informations RTTI dans les [[lib_fr:System.PackageInfoTable|tables d'information de packages]]. Cela signifie, qu'en C++, vous pouvez parcourir les informations RTTI pour les unités trouvées dans les modules {{Delphi}} (packages), comme dans le code suivant<source lang="cpp">
TRttiContext context;
TRttiType *rttiType = context.FindType("Classes.TStringList");
printf("%ls", rttiType->ToString()); // displays TStringList
</source>

<blockquote>'''Remarque&nbsp;:''' Sur la plate-forme iOS, la liaison est effectuée de façon statique, donc aucune information RTTI n'est enracinée. Cependant, vous pouvez obtenir les informations RTTI si vous utilisez la méthode '''[[lib_fr:System.Rtti.TRttiContext.GetType|GetType]]''', comme illustré dans l'exemple de code suivant&nbsp;: </blockquote>

<source lang="cpp">
TRttiContext context;
TRttiType *rttiType = context.GetType(__delphirtti(Fmx::Layouts::TLayout));

if (rttiType == NULL) {
ShowMessage("RTTI not generated");
} else {
ShowMessage(rttiType->ToString());
}
</source>

==Attributs==

Les attributs {{Delphi}} ne sont pas pris en charge dans {{CBuilder}}. {{CBuilder}} prend en charge les '''[[Fonctionnalités C++11 - Index|attributs C++11]]''', qui sont différents des attributs {{Delphi}} :

* Les attributs {{Delphi}} représentent des informations supplémentaires pour le programmeur et ils peuvent être extraits à l'exécution.
* Les attributs C++11 représentent des informations supplémentaires pour le compilateur et ne sont pas spécifiques à RTTI.

==Voir aussi==

===Informations RTTI de {{Delphi}}===

* [[lib_fr:System.Rtti|API RTTI]]
* [[Utilisation des informations RTTI - Index|Utilisation des informations RTTI]]
* [[Présentation des attributs|Attributs et RTTI]]

===Informations RTTI de {{Delphi}} dans {{CBuilder}}===

* [[Declspec(delphirtti)|__declspec(delphirtti)]]

===Informations RTTI de C++===

* [[Identification de type à l'exécution (RTTI) - Index|Identification de type à l'exécution (RTTI) - Index]]
* [[Typeid|typeid]] (mot clé)
* [[Rtti et option -RT|__rtti et option -RT]]

[[Category:Référence C++]]
[[Category:C++]]
[[Category:RTTI]]
14 347
modifications

Menu de navigation