Close

Relief for ODA Team in Ukraine

Learn more
ODA PRC SDK
Create Client Applications
This topic describes standard practice for creating custom client applications based on ODA PRC SDK.

Each custom application with .prc functionality should be correctly initialized and finished.

To initialize a custom application:

  1. Create an object that implements platform-dependent operations with files, databases, and PRC entities. See Creating Custom Application Services for details.
  2. Create custom assertion function and call it in the main () function to avoid application crash (for Debug configurations). See Customizing Assertion Function for Debug Configurations for details.
  3. Create instances of application services and initialize the ODA Platform environment. See Initialization of the ODA Platform Environment for details.

Creating Custom Application Services

To get access to ODA Software platform-dependent operations, create an application service object. This object can be an instance of your own class derived from classes provided with ODA Products.

In the other case, you can declare your own encapsulating OdExPrcHostAppServices, ExHostAppServices, and ExSystemServices classes functionality:


      template <class PrcHost = OdExPrcHostAppServices, class TdHost = ExHostAppServices, class exServices = ExSystemServices> 
      class MyServicesBase
      {
      OdStaticRxObject <PrcHost>    m_PrcHostAppServices;
      OdStaticRxObject <TdHost>     m_TdHostAppServices;
      OdStaticRxObject <exServices> m_systemServices;

      public:

        virtual OdDbSystemServices *systemServices() { return &m_systemServices; }
        virtual ExHostAppServices &hostTD() { return m_TdHostAppServices; }
        virtual OdExPrcHostAppServices &hostPRC() { return m_PrcHostAppServices; }

        virtual const OdDbSystemServices *systemServices() const { return &m_systemServices; }
        virtual const ExHostAppServices &hostTD() const { return m_TdHostAppServices; }
        virtual const OdExPrcHostAppServices &hostPRC() const { return m_PrcHostAppServices; }

        virtual ~MyServicesBase() {}
      };

      class MyServices : public MyServicesBase<>
      {
      };
    

The class OdExPrcHostAppServices implements platform-dependent operations with .prc file content. It is declared in the {ODA_DIR}\Prc\Extensions\ExServices\ExPrcHostAppServices.h file.

The class ExHostAppServices implements platform-dependent operations with databases and progress metering. It is declared in the {ODA_DIR}\Core\Extensions\ExServices\ExHostAppServices.h file.

The class ExSystemServices implements platform-dependent system operations with files and progress metering. It is declared in the {ODA_DIR}\Core\Extensions\ExServices\ExSystemServices.h file. Encapsulating ExSystemServices object is needed in the case when a client application should use ODA Kernel SDK functionality. If you intend to use onle ODA PRC SDK functionality, exclude ExSystemServices object from MyService class.

Customizing an Assertion Function for Debug Configurations

To avoid application crashes if an assertion fires, a custom assertion function can be created.

For example:


      static void MyAssert(const char* expression, const char* fileName, int nLineNo)
      {
        OdString message;
        message.format(L"\n!!! Assertion failed: \"%s\"\n    file: %ls, line %d\n", OdString(expression).c_str(), OdString(fileName).c_str(), nLineNo);
        odPrintConsoleString(message);
      }
    

The custom assertion function must have the same signature as the OdAssertFunc function pointer:


    typedef void (*OdAssertFunc) (
        const char* expresssion, 
        const char* filename, 
        int nLineNo);
    

To override the default assertion function, use the following construction in the main() function of a custom program:


      odSetAssertFunc(MyAssert);
    

Initialization of the ODA Platform environment

To create a set of application and system services, declare a MyService class instance on the stack:

      MyServices svcs;
    

ODA Platform environment initialization:


      odInitialize(svcs.systemServices());
    

Load PRC Module implements working with PRC format functionality:


      ::odrxDynamicLinker()->loadApp(OdPrcModuleName, false);
    

To get additional information about loading additional modules for client applications developed with ODA PRC SDK, see Loading Additional Libraries and Modules.

ODA Platform Environment Uninitialization

ODA Platform environment uninitialization must be done before exiting from a custom application.

To uninitialize the ODA Platform environment call the odUninitialize() function before returning the result value from the main () function:


      odUninitialize();
      return nRes; 
    

Loading Additional Libraries and Modules

A client application based on ODA PRC SDK can require optional libraries (or modules), which are used for implementing special functionality, for example, exporting operations.

Libraries and modules are available in two build versions: shared and static.

In the case when a client application uses shared versions of modules (.tx, .txv files), those modules should be allocated in the same directory of the client application.

Modules and libraries are loaded on demand or can be loaded explicitly using the OdRxDynamicLinker::loadModule() function, which accepts a module name as the first input parameter. The second parameter determines whether an exception should be thrown if the specified module or library is not found.


      ::odrxDynamicLinker()->loadModule(OdPrcModuleName, false);
    

By default, the second parameter value is equal to true (an exception is thrown).

If the client application uses shared ODA PRC SDK libraries, shared optional libraries and modules should be used. If ODA PRC SDK libraries are linked statically, static optional libraries and modules should be used.

In the case of static configuration, specify all the required modules in a module map before loading them. This action can be done by including special macros:


      #if !defined(_TOOLKIT_IN_DLL_) || defined(__MWERKS__)

      ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(ModelerModule);
      ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(OdPrcModule);
      ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(OdRecomputeDimBlockModule);

      ODRX_BEGIN_STATIC_MODULE_MAP()
      ODRX_DEFINE_STATIC_APPMODULE(OdModelerGeometryModuleName,       ModelerModule)
      ODRX_DEFINE_STATIC_APPLICATION(OdPrcModuleName, OdPrcModule)
      ODRX_DEFINE_STATIC_APPLICATION(OdRecomputeDimBlockModuleName,   OdRecomputeDimBlockModule)
      ODRX_END_STATIC_MODULE_MAP()

      #endif
    

After the module map has been declared, the application should use the ODRX_INIT_STATIC_MODULE_MAP macro once to initialize the static module map (before calling the odInitialize() function):


      #if !defined(_TOOLKIT_IN_DLL_) || defined(__MWERKS__)
        ODRX_INIT_STATIC_MODULE_MAP();
      #endif
      odInitialize(this);
    

See Also

Font Handling
Build PRC Sample Applications from Source Code
Copyright © 2002 – 2022. Open Design Alliance. All rights reserved.