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