ok, so after some tests and failures I got a way to achieve EXACTLY what I want to do.
My solution isn't straightforward... my fears come true...
After spending several hours to crawl on SO and internet ( like in a dark, cold and creepy dungeon, with my light torch and some Angelscourge's music ) I conclude there is NO such thing as a straightforward way!
/*...I can't blame a C lib to don't support some C++ feature...*/
so, I needed to found another strategy... so I heavily used my brain (a.k.a. headbanging)... there popped a solution :
/* The solution uses `libsigc++` AND a static function. */
The static function is in the namespace of the wrapper. This static function will do one thing, emit a signal. so if I take the same example as in the question,
namespace
IronMaiden
{
sigc::signal<int,void*,int,char**,char**> signalCB; // `extern` is a friend
.
.
.
static int
callback( void *PersonalUse
, int argc
, char **argv
, char **azColName )
{
return IronMaiden::signalCB.emit( PersonalUse, argc, argv, azColName);
}
.
.
.
int
BookOfSouls::MyWrapper( DB* db
, std::string& sql
, const sigc::slot<int,void*,int,char**,char**>& slotCB )
{
.
.
.
sigc::connection signalConnection = IronMaiden::signalCB.connect( slotCB );
sqlite3_exec( db->get(), sql.c_str(), callback, nullptr, nullptr);
signalConnection.disconnect();
.
.
.
}
}
To connect a (private member) function, let say YearOfTheGoat::ImTheCallbackFunction()
, from a YearOfTheGoat
object,
YearOfTheGoat::ImSomeFunctionFromWhereIWantToUseMyWrapper()
{
IronMaiden::MyWrapper( DBobj, transaction
, sigc::mem_fun(*this, &YearOfTheGoat::ImTheCallbackFunction) );
}
so now everytime that sqlite3_exec()
calls callback()
, that one will emit the signal, then calling ImTheCallbackFunction()
some important notes :
- in this example, the parameters and the return type of
ImTheCallbackFunction()
have to be identical to the ones of callback()
.
- be aware to disconnect or the signal will stay connected.
- I got no issue with that solution so far. But you have to understand I wrote this answer right after I wrote the code in my program. So I'm not gonna claim it's THE BEST solution. But it WORKS!
- note about
sqlite3_exec
, it seems that the cb function is called only if there is something to returns.
- don't be confused between
BookOfSouls
and YearOfTheGoat
. The first is NON instanciable. The second, I used an object. (N.B. since BookOfSouls
is non instanciable, moving callback
and sigc::signal
inside BookOfSouls
isn't a bad idea).
comments are very welcome