C++ Builder TypeInfo alternative.

I bet most Delphi developers know about TypeInfo operator. It provides type information somehow similar to reflection in Java or .NET (of course a lot more limited).

Take this simple example:

begin
  WriteLn(PTypeInfo(TypeInfo(Byte))^.Name);
end.

It will simply write “Byte” on the console, but it demonstrates how to use RTTI emitted type information properly.

Unfortunately C++ doesn’t emit this kind of RTTI for normal types but only for classes derived from TObject. Replicating the same code as in Delphi proves to be quite complicated. There is one method you can use to do it, and it involves some workarounds:

/*
Define a 2 macros to generate a local class that
exports RTTI info for a predefined property.
*/
#define MAKE_TYPEINFO(T) \
class T##_LOCAL_TYPE_INFO : public TObject \
{ \
private: \
T m_var; \
__published: \
__property T A_VAR = { read = m_var }; \
public: \
static PTypeInfo __fastcall TypeInfo() \
{ \
PTypeInfo pTInfo = (PTypeInfo)__typeinfo \
(T##_LOCAL_TYPE_INFO); \
PPropInfo pProp = Typinfo::GetPropInfo(pTInfo, “A_VAR”); \
return *(pProp->PropType); \
} \
static int __fastcall TypeSize() \
{ \
return sizeof(T); \
} \
}

#define GET_TYPE_INFO(T) T##_LOCAL_TYPE_INFO::TypeInfo()

/* Generate RTTI hack class */
MAKE_TYPEINFO(String);
int _tmain(int argc, _TCHAR* argv[])
{
cout << AnsiString(GET_TYPE_INFO(String)->Name).c_str() << endl; } [/sourcecode] Basically what happens is that MAKE_TYPEINFO macro will declare a new class that exposes a published property of the given type. The TypeInfo()function will then use this property to get to the actual RTTI of the type. GET_TYPE_INFO macro will simply invoke TypeInfo() function of the auto-generated class (to simplify coding). It’s not pretty but it works.

Node: You cannot use this technique on template classes unfortunately.

You May Also Like

About the Author: Alexandru Ciobanu

4 Comments

  1. This solution gives little-bit different results, compared to Delhi TypeInfo.
    For example RawByteString gives typename “AnsiString” (“RawByteString” in Delphi), String becomes to “UnicodeString” (“string” in Delphi), enums . When I tried to use these typeinfos in DataSnap context (see http://cc.embarcadero.com/item/27643), I got errors etc about unsupported types. Maybe setting manually typename (pProp->PropType->Name = #T;) can help, but is this safe to do?

  2. @Hanno
    Unsafe and you will most likely get an AV since the RTTI info is stored in read-only section (along with the code AFAIK).

    Plus DataSnap and C++ right now are not friends at all at the moment I’m afraid.

  3. @alex
    So looks like for getting correct typeinfo of String and RawByteString in C++ is needed to create helper functions in PAS, like:

    procedure GetTypeinfo_String: PTypeInfo;
    begin Result:=TypeInfo(String); end;

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.