Initializing a Library

Sometimes, a library needs to be initialized before it can provide any services to client of the library. This can be done in several ways.

Export functions for initializing and closing the library

The library can export more than one function for initializing and closing the library.

The client of the library calls the initialization function before requesting any services and calls close when the client does not use the library.

Example:

There is a DLL called xxx.dll. Two functions InitXXX() and CloseXXX() are exported from this DLL. The library code can look like the following:

Library header file xxx_init.h:

....
IMPORT_C void InitXXX();
IMPORT_C CloseXXX();
....

Library source file xxx_init.cpp:

static int _InitCount = 0;
EXPORT_C void InitXXX()
{
   if(_InitCount++ <= 0)
   {
   // initialize xxx.dll
   }
}
EXPORT_C CloseXXX()
{
   if(--_InitCount <= 0)
   {
   // free all the resources
   }
}

User code looks like the following:

#include <xxx_init.h>
...
int main()
{
   InitXXX();
   ....
   ....
   CloseXXX();
   return 0;
}

Exported functions check whether the library is initialized

Every exported function can check whether the library has been initialized. The library can export one function (for example, CloseLib()) and this can be called before exiting main().

Example:

Library header file xxx.h:

....
IMPORT_C void X_Export_Api1();
IMPORT_C void X_Export_Api2();
....

Library source file xxx.cpp:

static int _InitCount = 0;
#define INIT_LIB if(_InitCount == 0) \
           {\
               _InitCount++; \
               InitXXX(); \
           }
LOCAL_C void InitXXX()
{
   // initialize xxx.dll
}
LOCAL_C CloseXXX()
{
   // free all the resources
}
EXPORT_C void X_Export_Api1()
{
   INIT_LIB;
   ...
   ...
}

User code looks like the following:

#include <xxx.h>
...
int main()
{
   ....
   ....
   X_Export_Api1();
   ....
   ....
   X_Export_Api2();
   ....
   ....
   return 0;
}

Library defines a static object

The library can define static objects and call the initialization code from the constructor of these static objects so that before calling, the application entry point library will be initialized.

Example:

Library header file xxx.h:

....
IMPORT_C void X_Export_Api1();
IMPORT_C void X_Export_Api2();
....

Library source file xxx.cpp:

LOCAL_C void InitXXX()
{
   // initialize xxx.dll
}
LOCAL_C CloseXXX()
{
   // free all the resources
}
class LibInit
{
   LibInit();
   ~LibInit();
};
LibInit::LibInit()
{
   // put all library initialization code here.
   InitXXX();
}
LibInit::~LibInit()
{
   // free all resources
   CloseXXX();
}
static LibInit _libInit;

User code looks like the following:

#include <xxx.h>
int main()
{
   ....
   ....
   X_Export_Api1();
   ....
   ....
   X_Export_Api2();
   ....
   ....
   return 0;
}