C++ sqlite3 function pointer

Pages: 12
I tried every solution I know of, but it still give C3867 error for the way I used "callback" inside "checkexists" function. It seems I should refer to callback using pointers. How?

.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
  int myclass::callback(void* data, int argc, char** argv, char** coln)
{
    string val =  argv[0];
    if (val == "1") {
        return true;
    }

    return false;
}

bool myclass::checkexists(std::string coln, std::string tbln, std::string value) {

    char* err;
    string data("CALLBACK FUNCTION");
    
    sqlite3* mydb;
    sqlite3_open("myDB.db", &mydb);

    string sql(SQL STATEMENT GOES HERE);
    if (sqlite3_exec(mydb, sql.c_str(), callback, NULL, &err)) {
        cout << "\tAlready Exists!\n";
        return true;
    }
    sqlite3_close(mydb);

    return false;

}
Last edited on
<OP edited their post, making this post be rendered as nonsense>

Is myclass::callback a static function? Pointers to member functions can't be used in the same way as pointers to free functions. I would just make the callback function a free (non-class) function.

Also, what do you think that this line is doing?
string val = (coln[0], argv[0] ? argv[0] : "NULL");
Specifically, coln[0], argv[0]

Also, lines 27 - 29 are dead code, because you have an if-else chain that returns in both branches. You are never calling sqlite3_close, which I assume you should?
Last edited on
@Ganado

callback is static but we can't specify Storage class in .cpp. In header file it is set as static.

I was using callback for another select statement which i didn't fully change it here. Anyway, I made the changes you suggested. what's next?
Last edited on
If it was static then that wasn't the problem anyway. What the actual error message you originally got?

PS: Not related to the compiler error, but sqlite3_free() should be called on the error message you pass in.
Last edited on
See that void* parameter to callback? This is what it's for.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
int myclass::callback(void* data, int argc, char** argv, char**)
{
    // strictly speaking the first argument of type void* is no longer needed.
    assert(argc >= 1);
    return std::string_view{"1"} == argv[0];
}

static int callback_thunk(void* data, int argc, char** argv, char** coln)
{
  return reinterpret_cast<myclass*>(data)->callback(NULL, argc, argv, coln); 
}

bool myclass::checkexists(std::string coln, std::string tbln, std::string value) {

    char* err;
    string data("CALLBACK FUNCTION");
    
    sqlite3* mydb;
    sqlite3_open("myDB.db", &mydb);

    string sql(SQL STATEMENT GOES HERE);
    if (sqlite3_exec(mydb, sql.c_str(), callback_thunk, reinterpret_cast<void*>(this), &err)) {
        cout << "\tAlready Exists!\n";
        return true;
    }
    sqlite3_close(mydb);

    return false;
}
Wait but you can pass a static function as a non-class function pointer. What am I missing?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// Example program
#include <iostream>
#include <string>
using std::string;

using sqlite3 = int; // just for brevity

// https://sqlite.org/c3ref/exec.html
int sqlite3_exec(
  sqlite3*,                                  /* An open database */
  const char *sql,                           /* SQL to be evaluated */
  int (*callback)(void*,int,char**,char**),  /* Callback function */
  void *,                                    /* 1st argument to callback */
  char **errmsg                              /* Error msg written here */
)
{
    // blah
    return 0;
}

class myclass {
  public:
    static int callback(void* data, int argc, char** argv, char** coln)
    {
        if (argc <= 0) return 0;
        string val =  argv[0];
        return (int)(val == "1");
    }
    
    void foo()
    {
        sqlite3_exec(nullptr, nullptr, callback, nullptr, nullptr);
    }
};

int main()
{
    myclass myclass;
    myclass.foo();
}

(I don't care about the runtime of this example code, only that it compiles)
Last edited on
Nevermind, the discussion moved on while I was writing my post.
Last edited on
@mbozzi
Thanks! but VS still giving error C3867 (and red underline) for "callback_thunk" in "sql_checkexists"?!
Last edited on
Post the definition of your class. And you still haven't posted the actual error message! The C3867 code is not the full error message.
Last edited on
1
2
3
    static int callback (void*, int, char**, char**);
    static int callback_thunk(void*, int, char**, char**);
    bool checkexists(std::string, std::string, std::string);
In mbozzi's code, callback_thunk is a free function, not a static member. But you should be able to use a static function as a non-class function pointer, like I showed in my example, so the original problem is something else.
Last edited on
ok. defining static or non-static didn't make difference. VS error says:

"myClass::callback_thunk: non-standard syntax; use '&' to create a pointer member"

if it helps, i should say functions work fine in main.cpp, but after moving them to .h and .cpp, it started giving this error!

Thank you for your sample code. I'll try it!
Last edited on
It still thinks that your function is a member function.
Ganado wrote:
Post the definition of your class.
Last edited on
@mbozzi I did it up there.

I think something is wrong with the way they have been defined and implemented in .h and .cpp because as I said, if I declare and use them in main, they work fine!
Last edited on
I did it up there.

That is not the definition of your class. That's the definition of two member functions.

Help us help you.
Last edited on
Sorry for my ignorance. I'm new in cpp. Is this what you mean from .h ?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class myClass1 : public myClass0
{
public:

    myClass1();
    myClass1(std::string,std::string);
    ~myClass1();


        std::string getName() const;
	std::string getIdnum() const;

	void setName();
	void setIdnum();

    int callback(void*, int, char**, char**);
    int callback_thunk(void*, int, char**, char**);
    bool checkexists(std::string, std::string, std::string);

private:

    std::string newName;
    std::string newIdnum;

};
Last edited on
In your previous post with code in it, your callback functions had 'static' in their declaration. Now they don't. They need static (in the .h).
Last edited on
OMG, I'm sorry guys. I put back and forth a lot of code and its past 3am here.
Now that I added static again in .h it worked. Now there's no error but its not doing what my original source code was doing after @mbozzi changed it. I'll look at after a few hours of sleep ;)

Thanks to you guys!

Last edited on
@mbozzi
I don't know exactly what and why you did by splitting callback, but after the error was gone, the code wasn't doing what it meant to do.
So I made some changes as below and though it all works like charm now, I don't know what's really happening between two functions and generally what you did to make it work? would appreciate your explanation here.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int myClass::callback(void* data, int argc, char** argv, char**)
{
    return "1" == argv[0];
}

int myClass::callback_thunk(void* data, int argc, char** argv, char** coln)
{
    reinterpret_cast<myClass*>(data)->callback(NULL, argc, argv, coln);
    string val = argv[0];
    if (val == "1")
        return true;

    return false;
}
Pages: 12