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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With