Delphi RTTI and C++Builder
Go Up to Working with RTTI
Contents
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.
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:
- #pragma explicit_rtti (this is the C++ analog of {$RTTI})
- __declspec(delphirtti) (this is the C++ analog of {$M}/{$TYPEINFO})
- __published
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.