Delphi RTTI and C++Builder

From RAD Studio
Jump to: navigation, search

Go Up to Working with RTTI

Run-Time Type Discovery (Reflection)

Disambiguation

Delphi RTTI is different and separate from standard C++ RTTI:

  • Delphi RTTI allows you to explore the fields, methods, and so forth, of a class.
  • C++ RTTI allows you to identify the type of a variable and compare types for equality or collating order.
Note: The compiler option Project > Options > C++ Compiler > Enable RTTI' refers to standard C++ RTTI.

RTTI Generation

Only Delphi-style classes can have Delphi-style RTTI in C++ (see __declspec(delphiclass)).

RTTI can be generated for any kind of class member (methods, fields, properties) with any visibility (__published, public, protected, private). To control the RTTI generation, the following specifications can be used:

Example:

#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;
}

Console output:

wrHead: int @ 00

In this example, the class RTTI is extracted with the help of the __delphirtti function (which returns a pointer to a TTypeInfo variable). It is possible to do the same thing with the __classid operator. See the following code:

	TRttiInstanceType *cls = dynamic_cast<TRttiInstanceType*>
		(context.GetType(__classid(TBuffer)));

On the Windows platform, the __delphirtti of a wchar_t returns a PTypeInfo that matches Delphi's RTTI for the Delphi WideChar.

The functionality is shown in the following code example:

#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;
}

Output:

Platform Output

WIN64

Kind=1, Name='char16_t'

Kind=9, Name='Char'

Type Rooting

You cannot use the FindType and GetTypes methods to get Delphi RTTI for classes defined in C++ language. This is because FindType and GetTypes perform searches in the run-time packages, but there is no type rooting in C++ packages. This means you should not be able to use TRttiPackage to get information about a dynamic package built by C++Builder.

On the other hand, the Delphi linker roots the RTTI in package information tables. This means that in C++ you should be able to load and use Delphi-style RTTI from Delphi modules (packages), as in the following code:

TRttiContext context;
TRttiType *rttiType = context.FindType("Classes.TStringList");
printf("%ls", rttiType->ToString()); // displays TStringList

Attributes

Delphi attributes are not supported in C++Builder. C++Builder supports C++11 attributes, which are different from Delphi attributes:

  • Delphi attributes represent additional information for the programmer and can be extracted at run time.
  • C++11 attributes represent additional information for the compiler and are not specific to RTTI.

See Also

Delphi RTTI

Delphi RTTI in C++Builder

C++ RTTI