Delphi-RTTI und C++Builder

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu Mit RTTI arbeiten


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.
'Hinweis: Die Compiler-Option Projekt > Optionen > C++-Compiler > RTTI aktivieren' bezieht sich auf die Standard-C++RTTI.

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:

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.

Siehe auch

Delphi RTTI

Delphi-RTTI in C++Builder

C++-RTTI