Convert function type for sqlite callback

风流意气都作罢 提交于 2020-07-09 12:42:45

问题


I'm writing program using sqlite. I've got class dataSend_task, that periodicaly select data from BD and send it to server.

In dataSend_task i've got method callback, that I want to sent as argument to sqlite3_exec.

I've got error:

error: cannot convert ‘std::function<int(void*, int, char**, char**)>’ to ‘int (*)(void*, int, char**, char**)’ for argument ‘3’ to ‘int sqlite3_exec(sqlite3*, const char*, int (*)(void*, int, char**, char**), void*, char**)’
         if (sqlite3_exec(this->db, this->SQL_SELECT_READINGS_QUERY, callback, 0, &err)) {

Source code part:

int dataSend_task::callback(void *NotUsed, int argc, char **argv, char **columnName){...}

void dataSend_task::sendData()
{
    using namespace std::placeholders;
    std::function<int(void *, int, char **, char **)> callback = 
         std::bind(&dataSend_task::callback, this, _1, _2, _3, _4);

    if (sqlite3_exec(this->db, this->SQL_SELECT_READINGS_QUERY, 
                      callback, 0, &err)) 
    { ... }
}

As I understand problem is in converting callback to type that sqlite_exec accepts. But I don't know how to fix it.


回答1:


You cannot convert a std::function to a function pointer. However, you can still accomplish what you want with a lambda. Thanks to some sorcery, a lambda with no capture can be converted to a function pointer (exactly what you need). Notice also that sqlite3_exec() accepts a void* for the 1st argument - so you can use that in your no-capture lambda to actually call your member function:

if (sqlite3_exec(this->db, this->SQL_SELECT_READINGS_QUERY, 
    +[](void* instance, int x, char** y, char** z) {
        return static_cast<dataSend_task*>(instance)->callback(x, y, z);
    },
    this,
    &err))
{
    /* whatever */
}


来源:https://stackoverflow.com/questions/31461848/convert-function-type-for-sqlite-callback

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!