Delphi-RTTI und C++Builder
Nach oben zu Mit RTTI arbeiten
Inhaltsverzeichnis
Typermittlung zur Laufzeit (Überlegungen)
Begriffserklärung
Die Delphi-RTTI unterscheidet sich von der Standard-C++-RTTI:
- Mit der Delphi-RTTI lassen sich Felder, Methoden usw. einer Klasse untersuchen.
- Mit der C++-RTTI können Sie den Typ einer Variable ermitteln und Typen hinsichtlich Gleichheit oder Sortierreihenfolge vergleichen.
RTTI-Erzeugung
Nur Klassen im Delphi-Stil können in C++-RTTI-Informationen im Delphi-Stil haben (siehe __declspec(delphiclass)).
RTTI-Informationen können für alle Arten von Klassen-Membern (Methoden, Felder, Eigenschaften) mit jeder Sichtbarkeit (__published, public, protected, private) erzeugt werden. Zur Steuerung der RTTI-Erzeugung können die folgenden Spezifikationen verwendet werden:
- #pragma explicit_rtti (dies ist die C++-Entsprechung für {$RTTI})
- __declspec(delphirtti) (dies ist die C++-Entsprechung für {$M}/{$TYPEINFO})
- __published
Ein Beispiel:
#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;
}
Konsolenausgabe:
wrHead: int @ 00
In diesem Beispiel wird die Klasse RTTI mit der Funktion __delphirtti (die einen Zeiger auf eine TTypeInfo-Variable zurückgibt) extrahiert. Dasselbe können Sie mit dem Operator __classid ausführen. Siehe den folgenden Code:
TRttiInstanceType *cls = dynamic_cast<TRttiInstanceType*>
(context.GetType(__classid(TBuffer)));
Auf der Windows-Plattform gibt __delphirtti eines wchar_t eine PTypeInfo zurück, die den RTTI von Delphi für Delphi-WideChar entspricht.
Diese Funktionalität wird in dem folgenden Codebeispiel gezeigt:
#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;
}
Ausgabe:
| Plattform | Ausgabe |
|---|---|
|
WIN64 |
Kind=1, Name='char16_t' Kind=9, Name='Char' |
Typ-Rooting
Delphi-RTTI-Informationen für in der Sprache C++ definierte Klassen können nicht mit den Methoden FindType und GetTypes ermittelt werden. Das liegt daran, dass FindType und GetTypes Suchen in Laufzeit-Packages durchführen, es aber in C++-Packages kein Typ-Rooting gibt. Das bedeutet, dass Sie mit TRttiPackage keine Informationen zu einem dynamischen, mit C++Builder erzeugten Package abrufen können.
Andererseits weist der Delphi-Linker die RTTI-Informationen in Package-Informationstabellen aus. Das bedeutet, dass Sie in C++ RTTI im Delphi-Stil aus Delphi-Modulen (Packages) laden und verwenden können, wie im folgenden Code:
TRttiContext context;
TRttiType *rttiType = context.FindType("Classes.TStringList");
printf("%ls", rttiType->ToString()); // displays TStringList
Attribute
Delphi-Attribute werden in C++Builder nicht unterstützt. C++Builder unterstützt C++11-Attribute, die sich von Delphi-Attributen unterscheiden:
- Delphi-Attribute stellen zusätzliche Informationen für den Programmierer dar und können zur Laufzeit extrahiert werden.
- C++11-Attribute stellen zusätzliche Informationen für den Compiler dar und sind nicht spezifisch für RTTI.