好的,所以经过一些测试和失败后,我找到了一种方法来实现我想要做的事情。
我的解决方案并不简单……我的恐惧成真了……
在花了几个小时在 SO 和互联网上爬行(就像在一个黑暗、寒冷和令人毛骨悚然的地牢中,用我的手电筒和一些 Angelscourge 的音乐)后,我得出结论,没有一种直截了当的方法!
/*...I can't blame a C lib to don't support some C++ feature...*/
所以,我需要找到另一种策略......所以我大量使用我的大脑(又名headbanging)......出现了一个解决方案:
/* The solution uses `libsigc++` AND a static function. */
静态函数位于包装器的命名空间中。这个静态函数会做一件事,发出一个信号。所以如果我举与问题相同的例子,
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();
.
.
.
}
}
要连接一个(私有成员)函数,比如说YearOfTheGoat::ImTheCallbackFunction()
,从一个YearOfTheGoat
对象,
YearOfTheGoat::ImSomeFunctionFromWhereIWantToUseMyWrapper()
{
IronMaiden::MyWrapper( DBobj, transaction
, sigc::mem_fun(*this, &YearOfTheGoat::ImTheCallbackFunction) );
}
所以现在每次sqlite3_exec()
调用callback()
时,都会发出信号,然后调用ImTheCallbackFunction()
一些重要的注意事项:
- 在此示例中, 的参数和返回类型
ImTheCallbackFunction()
必须与 的相同callback()
。
- 请注意断开连接,否则信号将保持连接状态。
- 到目前为止,我对该解决方案没有任何问题。但是您必须了解我在程序中编写代码后立即编写了此答案。所以我不会声称这是最好的解决方案。但它有效!
- 请注意
sqlite3_exec
,似乎只有在有要返回的内容时才调用 cb 函数。
- 不要混淆
BookOfSouls
和YearOfTheGoat
。第一个是不可实例化的。第二,我使用了一个对象。(注意,因为BookOfSouls
它是不可实例化的,所以移动callback
和sigc::signal
内部BookOfSouls
并不是一个坏主意)。
非常欢迎评论