Initializing the |me_h| Library =============================== .. highlight:: c |me| has been designed to integrate with a wide range of operating systems, network stacks, and CPUs. For this reason, |me| places few restrictions on how it is integrated. The memory management API defined by |me| may be implemented using standard C libray APIs such as *malloc()* and *free()*, or something hardware specific relying on memory being allocated from a specific memory region. In order to allow a degree of flexibility, integrations may be configurable at run-time. This configuration may require validation before it is safe to make specific calls, such as allocating memory. In order to guarantee consistency accross all integrations for when it is safe to call APIs, |me| requires that its library is initialized with *DDS_DomainParticipantFactory_get_instance* before any public APIs are called, unless an API is documented to be safe to call before *DDS_DomainParticipantFactory_get_instance*. *DDS_DomainParticipantFactory_get_instance* initializes an integration, providing an opportunity for integrations to validate its configuration. .. note:: This restriction is not limited to DDS APIs, but extends to **all** public APIs, such as sequence APIs, type-support APIs, string APIs, and component APIs. |me| is initialized with a successful call to *DDS_DomainParticipantFactory_get_instance*. On success, *DDS_DomainParticipantFactory_get_instance* returns a reference to a *DDS_DomainParticipantFactory*; on failure, 'nil' is returned: :: DDS_DomainParticipantFactory *factory = NULL; factory = DDS_DomainParticipantFactory_get_instance(); if (factory == NULL) { /* something failed, exit */ exit(-1); } /* Safe to call other public APIs */ After a successful call to *DDS_DomainParticipantFactory_get_instance*, public APIs are safe to call as documented. APIs that **must not** be called before *DDS_DomainParticipantFactory_get_instance* have the following additional description: .. code-block:: none API Restriction: This function must only be called after DDS_DomainParticipantFactory_get_instance. .. warning:: *DDS_DomainParticipantFactory_get_instance* is not guarenteed to be thread-safe. rtiddsgen --------- *rtiddsgen* is the type support compiler included with |me|. *rtiddsgen* generates code to send and receive data types across the network, as well as to allocate memory to store data types in memory. These memory allocations use the memory management APIs defined by |me|. Because each integration determines how these APIs are implemented, it is important that TypeSupport APIs are **not** called until |me| has been initialized. APIs such as *FooTypeSupport_create_data* and *FooTypeSupport_delete_data* are **not** safe to call until after a successful call to *DDS_DomainParticipantFactory_get_instance*: :: DDS_DomainParticipantFactory *factory = NULL; Foo *sample = NULL; /* NOT ALLOWED */ sample = FooTypeSupport_create_data(); factory = DDS_DomainParticipantFactory_get_instance(); if (factory == NULL) { /* something failed, exit */ exit(-1); } /* ALLOWED */ sample = FooTypeSupport_create_data(); if (sample == NULL) { /* something failed, exit */ exit(-1); } /* Calls other public APIs */ The |me_h| System API --------------------- The |me| System API enables applications to configure the behavior of |me| at runtime. Which configuration options are available depends on the specific integration. However, because the |me| system must be configured **before** |me| is initialized, it is safe to call public System APIs before *DDS_DomainParticipantFactory_get_instance*, such as *OSAPI_System_get_property* and *OSAPI_System_set_property*: :: struct OSAPI_SystemProperty sys_property = OSAPI_SystemProperty_INITIALIZER; DDS_DomainParticipantFactory *factory = NULL; if (!OSAPI_System_get_property(&sys_property)) { /* error */ return; } /* Set sys_property */ if (!OSAPI_System_set_property(&sys_property)) { /* error */ return; } factory = DDS_DomainParticipantFactory_get_instance(); if (factory == NULL) { /* error */ return; } Component Registration ---------------------- |me| consists of core APIs and additional components that extend its functionality. |me| includes two components which **must** always be registered with |me| before any DDS entities can be created: the *writer* and *reader* history caches. The following code sample demonstrates how to register these: :: #include "wh_sm/wh_sm_history.h" #include "rh_sm/rh_sm_history.h" DDS_DomainParticipantFactory *factory = NULL; RT_Registry_T *registry = NULL; factory = DDS_DomainParticipantFactory_get_instance(); if (factory == NULL) { /* something failed, exit */ exit(-1); } registry = DDS_DomainParticipantFactory_get_registry(factory); if (registry == NULL) { /* something failed, exit */ exit(-1); } if (!RT_Registry_register(registry, DDSHST_WRITER_DEFAULT_HISTORY_NAME, WHSM_HistoryFactory_get_interface(), NULL, NULL)) { /* something failed, exit */ exit(-1); } if (!RT_Registry_register(registry, DDSHST_READER_DEFAULT_HISTORY_NAME, RHSM_HistoryFactory_get_interface(), NULL, NULL)) { /* something failed, exit */ exit(-1); } |me| includes other components, such as :doc:`discovery` plugins and the :doc:`transports/UDP`. These are documented in other sections.