Syntax
int _rmem_init(void); /* no header file - defined in run-time startup code */Description
By default, all DLLs call The Developer's Toolkit _DLL_InitTerm function, which in turn calls _rmem_init for you. However, if you are writing your own subsystem _DLL_InitTerm function (for example, to perform actions other than memory initialization and termination), you must call _rmem_init from your version of _DLL_InitTerm before you can call any other library functions.
If your DLL contains C++ code, you must also call __ctordtorInit after _rmem_init to ensure that static constructors and destructors are initialized properly. __ctordtorInit is defined in the run-time startup code as:
void __ctordtorInit(void);
If the memory functions were successfully initialized, _rmem_init returns 0. A return code of -1 indicates an error. If an error occurs, an error message is written to file handle 2, which is the usual destination of stderr.
The following example shows the _DLL_InitTerm function from The Developer's Toolkit sample program for building subsystem DLLs, which calls _rmem_init to initialize the memory functions.
#pragma strings( readonly )
/******************************************************************************/
/*                                                                            */
/* _DLL_InitTerm - Initialization/Termination function for the DLL that is    */
/*                 invoked by the loader.                                     */
/*                                                                            */
/* DLLREGISTER  - Called by _DLL_InitTerm for each process that loads the     */
/*                DLL.                                                        */
/*                                                                            */
/* DLLDEREGISTER- Called by _DLL_InitTerm for each process that frees the     */
/*                DLL.                                                        */
/*                                                                            */
/******************************************************************************/
#define  INCL_DOS
#define  INCL_DOSERRORS
#define  INCL_NOPMAPI
#include <os2.h>
#include <stdio.h>
unsigned long _DLL_InitTerm( unsigned long hModule, unsigned long ulFlag );
static unsigned long DLLREGISTER( void );
static unsigned long DLLDEREGISTER( void );
#define SHARED_SEMAPHORE_NAME "\\SEM32\\SAMPLE05\\DLL.LCK"
/* The following data will be per-process data.  It will not be shared among  */
/* different processes.                                                       */
static HMTX  hmtxSharedSem;    /* Shared semaphore                            */
static ULONG ulProcessTotal;   /* Total of increments for a process           */
static PID   pidProcess;       /* Process identifier                          */
/* This is the global data segment that is shared by every process.           */
#pragma data_seg( GLOBAL_SEG )
static ULONG ulProcessCount;                /* total number of processes      */
/* _DLL_InitTerm() - called by the loader for DLL initialization/termination  */
/* This function must return a non-zero value if successful and a zero value  */
/* if unsuccessful.                                                           */
unsigned long _DLL_InitTerm( unsigned long hModule, unsigned long ulFlag )
   {
   APIRET rc;
   /* If ulFlag is zero then initialization is required:                      */
   /*    If the shared memory pointer is NULL then the DLL is being loaded    */
   /*    for the first time so acquire the named shared storage for the       */
   /*    process control structures.  A linked list of process control        */
   /*    structures will be maintained.  Each time a new process loads this   */
   /*    DLL, a new process control structure is created and it is inserted   */
   /*    at the end of the list by calling DLLREGISTER.                       */
   /*                                                                         */
   /* If ulFlag is 1 then termination is required:                            */
   /*    Call DLLDEREGISTER which will remove the process control structure   */
   /*    and free the shared memory block from its virtual address space.     */
   switch( ulFlag )
      {
   case 0:
         if ( !ulProcessCount )
            {
            _rmem_init();
            /* Create the shared mutex semaphore.                             */
            if ( ( rc = DosCreateMutexSem( SHARED_SEMAPHORE_NAME,
                                           &hmtxSharedSem,
                                           0,
                                           FALSE ) ) != NO_ERROR )
               {
               printf( "DosCreateMutexSem rc = %lu\n", rc );
               return 0;
               }
            }
         /* Register the current process.                                     */
         if ( DLLREGISTER( ) )
            return 0;
         break;
      case 1:
         /* De-register the current process.                                  */
         if ( DLLDEREGISTER( ) )
            return 0;
         _rmem_term();
         break;
      default:
         return 0;
      }
   /* Indicate success.  Non-zero means success!!!                            */
   return 1;
   }
/* DLLREGISTER - Registers the current process so that it can use this        */
/*               subsystem.  Called by _DLL_InitTerm when the DLL is first    */
/*               loaded for the current process.                              */
static unsigned long DLLREGISTER( void )
   {
   APIRET rc;
   PTIB ptib;
   PPIB ppib;
   /* Get the address of the process and thread information blocks.           */
   if ( ( rc = DosGetInfoBlocks( &ptib, &ppib ) ) != NO_ERROR )
      {
      printf( "DosGetInfoBlocks rc = %lu\n", rc );
      return rc;
      }
   /* Open the shared mutex semaphore for this process.                       */
   if ( ( rc = DosOpenMutexSem( SHARED_SEMAPHORE_NAME,
                                &hmtxSharedSem ) ) != NO_ERROR )
      {
      printf( "DosOpenMutexSem rc = %lu\n", rc );
      return rc;
      }
   /* Acquire the shared mutex semaphore.                                     */
   if ( ( rc = DosRequestMutexSem( hmtxSharedSem,
                                   SEM_INDEFINITE_WAIT ) ) != NO_ERROR )
      {
      printf( "DosRequestMutexSem rc = %lu\n", rc );
      DosCloseMutexSem( hmtxSharedSem );
      return rc;
      }
   /* Increment the count of processes registered.                            */
   ++ulProcessCount;
   /* Initialize the per-process data.                                        */
   ulProcessTotal = 0;
   pidProcess = ppib->pib_ulpid;
   /* Tell the user that the current process has been registered.             */
   printf( "\nProcess %lu has been registered.\n\n", pidProcess );
   /* Release the shared mutex semaphore.                                     */
   if ( ( rc = DosReleaseMutexSem( hmtxSharedSem ) ) != NO_ERROR )
      {
      printf( "DosReleaseMutexSem rc = %lu\n", rc );
      return rc;
      }
   return 0;
   }
/* DLLDEREGISTER - Deregisters the current process from this subsystem.       */
/*                 Called by _DLL_InitTerm when the DLL is freed for the      */
/*                 last time by the current process.                          */
static unsigned long DLLDEREGISTER( void )
   {
   APIRET rc;
   /* Acquire the shared mutex semaphore.                                     */
   if ( ( rc = DosRequestMutexSem( hmtxSharedSem,
                                   SEM_INDEFINITE_WAIT ) ) != NO_ERROR )
      {
      printf( "DosRequestMutexSem rc = %lu\n", rc );
      return rc;
      }
   /* Decrement the count of processes registered.                            */
   --ulProcessCount;
   /* Tell the user that the current process has been deregistered.           */
   printf( "\nProcess %lu has been deregistered.\n\n", pidProcess );
   /* Release the shared mutex semaphore.                                     */
   if ( ( rc = DosReleaseMutexSem( hmtxSharedSem ) ) != NO_ERROR )
      {
      printf( "DosReleaseMutexSem rc = %lu\n", rc );
      return rc;
      }
   /* Close the shared mutex semaphore for this process.                      */
   if ( ( rc = DosCloseMutexSem( hmtxSharedSem ) ) != NO_ERROR )
      {
      printf( "DosCloseMutexSem rc = %lu\n", rc );
      return rc;
      }
   return 0;
   }
Related Information