Kernel SDK Developer's Guide > Run-Time Type Identification > Functionality of RTTI
Functionality of RTTI

The OdRxClass class supports standard reference counting functionality and provides RTTI functionality, which is defined only for registered classes derived from the OdRxObject class. The class must declare the RTTI methods using the ODRX_DECLARE_MEMBERS macro in its own public section and define their implementation using one of the ODRX_**_DEFINE_MEMBERS_** macros in the cpp-code. If a class is not registered, its RTTI methods generate the eNotApplicable exception.

For example, the following xMyCls class is derived from the OdRxObject class and has the "MyClass" class name, the "acMYCLASS" dxf class name, "MyApp" application class name, R14 dwg version, 2 release version, and kEraseAllowed & kCloningAllowed proxy flags. The xMyCls class must have the following definition:

#include "OdaCommon.h"
#include "OdToolKit.h"
#include "..\..\Teigha.dwg\Extensions\ExServices\ExHostAppServices.h"
#include "..\..\Teigha.dwg\Extensions\ExServices\ExSystemServices.h"

class xMyCls : public OdRxObjectImpl<OdRxObject>
{
 public:
   ODRX_DECLARE_MEMBERS(xMyCls);                     // Declaring of the RTTI methods
   xMyCls() {};
   ~xMyCls() {};
};                                                   // Implementing of the RTTI methods

ODRX_DEFINE_MEMBERS(xMyCls, OdRxObject, NEWOBJ_CONSTR, kDHL_1014, kMRelease2, 0x81, "MyClass", "acMYCLASS", "MyApp");

The xMyCls class must be registered in the main program using the rxInit() static method before applying RTTI methods. To get the class describing instance, use the desc() static method to return the smart pointer of the OdRxClass type referring to the class describing instance that is statically associated with this registered class.

class MyApp : public ExSystemServices 
{
 protected:
   ODRX_USING_HEAP_OPERATORS(ExSystemServices);
   MyApp() {};
};

void main()
{
   OdStaticRxObject<MyApp> svcs;
   odInitialize(&svcs);
   xMyCls::rxInit();                                 // Registering of the class
	
   OdRxClassPtr pCls = xMyCls::desc();               // Getting of the class describing instance
	
   // Here, past a one of cpp-codes described below 
	
   xMyCls::rxUninit();                               // Unregistering of the class
   odUninitialize();
}	

To get the address of the class describing instance, use the get() method of the returned smart pointer. For example:

odPrintConsoleString(L"\nThe class describing instance = %x", pCls.get());                // Prints:  = 14A208

To get the class name, use the name() method that returns the name of the registered class as a string of the OdString type. For example:

odPrintConsoleString(L"\nThe class name = %s", pCls->name().c_str());                     // Prints:  = MyClass

To get the dxf class name, use the dxfName() method that returns the name of the dxf class as a string of the OdString type. For example:

odPrintConsoleString(L"\nThe dxf class name = %s", pCls->dxfName().c_str());              // Prints:  = acMYCLASS

To get the application class name, use the appName() method that returns the name of the application as a string of the OdString type. For example:

odPrintConsoleString(L"\nThe application class name = %s", pCls->appName().c_str());      // Prints:  = MyApp

To get the parent class, use the myParent() method that returns the raw pointer to the class describing instance that describes the parent class as a pointer of the OdRxClass type. For example:

odPrintConsoleString(L"\nThe parent class name = %s", pCls->myParent()->name().c_str());  // Prints:  = OdRxObject

To get the proxy flags, use the proxyFlags() method that returns a bit mask as an integer value of the OdUInt32 type. For example:

odPrintConsoleString(L"\nThe proxy flags = %x", pCls->proxyFlags());                      // Prints:  = 0x81

To get the custom flags, use the customFlags() method that returns a bit mask as an integer value of the OdUInt32 type. For example:

odPrintConsoleString(L"\nThe custom flags = %x", pCls->customFlags());                      // Prints:  = 0

To get the maintenance version and .dwg file version, use the getClassVersion() method which returns the .dwg file version number and requires a raw pointer to the variable in which this method saves the maintenance release version number. The MaintReleaseVer enumeration defines the maintenance release versions. The DwgVersion enumeration defines the .dwg file versions. For example:

OdDb::MaintReleaseVer nMaintVer;
OdDb::DwgVersion nDwgVer = pCls->getClassVersion(&nMaintVer);

odPrintConsoleString(L"\nMaintain version = %d", nMaintVer);                              // Prints:  = 2
odPrintConsoleString(L"\nDWG version = %d", nDwgVer);                                     // Prints:  = 21

To get the module in which the class resides, use the module() method that returns the raw pointer to the module. For example:

OdRxModule pModule = pCls->module();

If(pModule != NULL)
  odPrintConsoleString(L"\nThe module name = %s", pModule->moduleName().c_str());

To get the callback function which is called when a registered object is to be saved, use the appNameCallbackPtr() method that returns a pointer to the callback function. For example:

AppNameChangxFuncPtr pFunc = pCls->appNameCallbackPtr();

If(pFunc != NULL)
  odPrintConsoleString(L"\nThe callback function is set");

Note: A custom class can alter its application name depending on file format version it's being saved to. This alteration is implemented using the callback function pointer passed as an argument to the rxInit() function and has an effect only when saving to a file (.dwg or .dxf). For example, a custom object being saved to 2004 format can be saved with the application name "Aec40", being saved to 2007 file format with application name "Aec70", etc. The run-time application name returned by appName() is always the same.

To check whether the xMyCls class is derived from the OdRxObject class, use the isDerivedFrom() method which requires a raw pointer to the class describing instance as an argument and returns True when the class is derived from the specified class or returns False otherwise. For example:

odPrintConsoleString(L"\nxMyCls is derived from OdRxObject = %s", 
                    (pCls->isDerivedFrom(OdRxObject::desc())) ? L"true" : L"false");      // Prints:  = true

See Also

RTTI Technology

Implementing RTTI Methods for the Derived Class

Implementing the Class Describing Structure

Registering and Unregistering Classes in a Program

Copyright © 2002 – 2020. Open Design Alliance. All rights reserved.