SQLite User Forum

callback
Login

callback

(1) By Chris Moore (Chrismoore) on 2022-08-10 21:50:32 [link] [source]

C++ Visual Studio - I am executing a function outside of a class. This function opens the database, formats the SQL, and then calls sqlite3_exec. sqlite3.exec does not seem to be calling callback. my callback function is also outside the class and it is the first function in the source member. Callback doesn't even get to the first line of the function (where I have a debug breakpoint that is never triggers. I tested the SQL statement in another program and it works. sqlite3_exec returns a 0 too. If I try to move the 2 functions inside the class the compile fails on the callback argument in sqlite3_exec. So if I have:

callback() intsql () - a function that calls sqlite3_exec the class

callback does not seem to ever be called. intsql is called inside the class by another function and that is working just fine. If I don't put callback before intsql then intsql will not compile because it does not know what callback is. I also tried:

callback() the class (with intsql in it at the end)

same issue - callback() is never executed

Any ideas?

(2.1) By Larry Brasfield (larrybr) on 2022-08-10 22:54:29 edited from 2.0 in reply to 1 [source]

Because you use strange terminology to refer to the objects involved in your discontent, it is doubly important to show the code which is not acting as you wish. This would be important even if you were familiar with conventional terminology.

(Added via edit:)

I have too many ideas regarding what you have done futilely to be guessing. However, the following brief program demonstrates how something similarly describable could be done. Perhaps seeing how this differs from you code may help.

#include <iostream>
#include "sqlite3.h"

struct Gizmo {
  static int call_me(void *pvData, int nc, char **azData, char **azNames){
    for( int i=0; i<nc; ++i ){
      std::cout << azNames[i] << ':' << azData[i];
    }
    std::cout << "\n";
    return 0;
  }
};

int main(int na, char *azArgs[]){
  sqlite3 * db = 0;
  sqlite3_open(":memory:", &db);
  sqlite3_exec(db, "SELECT 1 AS One", Gizmo::call_me, 0, 0);
}

(3) By Chris Moore (Chrismoore) on 2022-08-11 01:12:21 in reply to 2.1 [link] [source]

Larry

Thanks for responding so quickly and getting to the point. Your example matches very well to the code I have where intsql and callback are functions above main. That version works.

HERE IS WHAT THE ONE THAT WORKS LOOKS LIKE:

static int callback(void* NotUsed, int argc, char** argv, char** azColName) { int i = 0; string tb = "t";

for (i = 0; i < argc; i++) {

    cout << azColName[i] << ": " << tb;
    if (strlen(azColName[i]) < 8) cout << tb;
    cout << argv[i] << endl;

}

int litsql() { .... sqlite3* db; int rc; char* sql;

sql = ...

char* zErrMsg = 0;
const char* data = "Callback function called";

/* Execute SQL statement */
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);

.... }

main(){

int s = 0;
s = litsql();

}

in this top one the 2 functions are above and outside of main.

HERE IS THE ONE THAT DOESN'T WORK:

static int callback(void* NotUsed, int argc, char** argv, char** azColName) { int i = 0; int j = 0; for (i = 0; i < argc; i++) {

std::string scs = azColName[i];

}

litsql() {

char* zErrMsg = "0"; const char* data = "Callback function called"; /* Execute SQL statement */ rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);

sqlite3_close(db);

}

In this bottom example callback is outside the class and litsql is a function at the bottom inside the class. In the second example I can see output right before and after my sqlite3_exec call. But when I put a debug breakpoint on int i=0 in callback it never gets there.

If you use a function outside of a class does it need to be defined in the class?

(4) By Larry Brasfield (larrybr) on 2022-08-11 01:55:04 in reply to 3 [link] [source]

I'm perplexed by several aspects of your code shown in post #3.

In your "WORKS" code, the callback prints something whereas in your "DOESN'T WORK" code, nothing is done at all that could not be legitimately optimized away. If it at least did something that could affect the rest of the world (besides hopefully hitting a breakpoint), then I would assign significance to not hitting a breakpoint. But because the callback body could optimize to nothing, I infer nothing from your not seeing it hit.

You mention "class" here and there, and where things are relative to "the class", but I see no code that declares or defines a class or any members of one.

You write "litsql is a function at the bottom inside the class" but that is not evident from the code you post. The function you did post has no return type, making me think it cannot be actual code that a compiler was willing to translate into machine instructions.

I would urge you to simplify an example showing your puzzlement and post it as a standalone, compilable program. There are plenty of C++ programmers who frequent this forum (including me), so that should lead quickly to a resolution.

If you use a function outside of a class does it need to be defined in the class?

I'm not sure what the question means. A member function can be declared for a class, within the class definition, then used by other member functions or, with adequate visibility (public or protected), used in other contexts. It does not matter where functions are defined (if defined somewhere); what matters is where they are declared. These issues would be made more concrete and readily discussed if they pertained to real code acceptable to a C++ compiler.

(5) By Chris Moore (Chrismoore) on 2022-08-11 02:58:37 in reply to 4 [link] [source]

Larry

The class "Form1" is doing many other things - can I attach a copy of the source somehow? The program does compile and runs - it just never seems to get to callback.

Because this program is a C++ Windows form type program, standard out is not available. So instead I am using the System::Diagnostics::Debug::WriteLine function to write out to the Debug window (similar to how you used cout in your original example). When I copy my SQL select statement to another program that uses the same database the values come write out. But that code has 2 functions defined above a main, and no class definitions. I put several WriteLine's in my callback function but none of them are showing up, and that's when I put the breakpoint on.

The program shows me the select statement (sqlstr) and rc comes back as a 0 and I see SQL Execute Successful. And again I tested the same select code in the working version and the correct results came right out.

/* Create SQL statement / char sql; if (sqlstr->Length < sizeof(sql)) sprintf(sql, "%s", sqlstr); System::Diagnostics::Debug::WriteLine(sqlstr);

   char* zErrMsg = "0";
   const char* data = "Callback function called";
   /* Execute SQL statement */
   rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
   sqlite3_close(db);
   if (rc) {
      System::Diagnostics::Debug::WriteLine("SQL Error");
      std::string ers = zErrMsg;
      String^ errstr = gcnew String(ers.c_str());
      System::Diagnostics::Debug::WriteLine(errstr);
      sqlite3_free(zErrMsg);
      return 1;
   }
   else {
      System::Diagnostics::Debug::WriteLine("SQL Execute Successful");
      return 0;
   }

(6) By Chris Moore (Chrismoore) on 2022-08-11 03:15:55 in reply to 5 [link] [source]

Larry

Writing to you helped me figure it out. Although I am building sqlstr and sending that to the Debug Window and it is correct, I am calling sqlite3_exec with sql. When I debugged that it was all zeros. Apparently the sprintf is not working write - I will fix it - that should solve the problem!

(7) By Chris Moore (Chrismoore) on 2022-08-11 15:11:01 in reply to 6 [link] [source]

Just to close out this issue: Larry's suggestion that I show him (and everyone) what code was WORKING and what WAS NOT WORKING made me put the code side by side, and then I saw my error. It is a practice we should all continue to use.

I was calling sqlite3_exec with a blank or zero sql parameter. If the parameter had an invalid keyword or erroneous punctuation sqlite3_exec would have returned a 1. But if the sql parameter is just blank, sqlite3_exec skips executing callback() and still returns a 0. Of course a blank sql statement appears to be valid - it just does nothing.

The position and declaration and definition of the callback function had nothing to do with the error. When I put callback inside of my class code other functions in the class code that used callback would not compile. So I put the callback function above the class code in my source member and everything did compile and run without any other issues. I DID NOT need any special definitions or declarations related to the callback function inside the class. Because the callback function was outside the class, I had to use an external variable to store the value I got from callback and then use it later inside the class. It was just a single string variable where I save input from a Windows form, use the value to look up a record in my SQLITE database, and then output another field value from the record retrieved back to the form.

(8) By Stephan Beal (stephan) on 2022-08-11 15:52:15 in reply to 7 [link] [source]

and then I saw my error. ... if the sql parameter is just blank, sqlite3_exec skips executing callback() and still returns a 0. Of course a blank sql statement appears to be valid - it just does nothing.

If it makes you feel any better, you're not the only person who's ever stumbled over that. (Who, me?)