Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Common pattern for library initialization and shutdown?

Is there a pattern that I may use for calling the required initialization and cleanup routines of an underlying (C) library? In my case, I would like to create the wrapper class so that it can be composed into other objects. The problem is that, when I destroy the wrapper class, the cleanup routines of the underlying library are called. That's fine until I instantiate multiple objects of my wrapper class. My question is what is the best way to really handle this situation? A static reference counter comes to mind, but I wanted to know if there were other potentially better options and the trades involved.

like image 744
jdt141 Avatar asked Feb 07 '10 05:02

jdt141


2 Answers

Not everything has to be a class. The Singleton pattern would let you turn this into a class, but it's really not buying you anything over global functions:

bool my_library_init();
void my_library_shutdown();

The first call returns true if the library was successfully initialized, the second just quietly does whatever needs to be done and exits. You can add whatever reference counting or thread tracking type stuff behind these interfaces you like.

Also, don't neglect the possibility that your library may be able to do all of this transparently. When the first library function is called, could it detect that it is not initialized yet and set everything up before doing the work? For shutdown, just register the resources to be destroyed with a global object, so they are destroyed when the program exits. Doing it this way is certainly trickier, but may be worth the usability benefit to your library's callers.

like image 161
Warren Young Avatar answered Oct 18 '22 20:10

Warren Young


If the initialization can be called before main starts, and cleanup called after main ends, this little trick (hack?) might work for you:

#include <iostream>

// C library initialization routine
void init() {std::cout << "init\n";}

// C library cleanup routine
void fini() {std::cout << "fini\n";}

// Put this in only one of your *.cpp files
namespace // anonymous
{
    struct Cleaner
    {
        Cleaner() {init();}
        ~Cleaner() {fini();}
    };
    Cleaner cleaner;
};

int main()
{
    std::cout << "using library\n";
}

Output:

init
using library
fini

It uses (abuses?) the fact that constructors for static objects are called before main, and that destructors are called after main. It's like RAII for the whole program.

like image 7
Emile Cormier Avatar answered Oct 18 '22 19:10

Emile Cormier