I'm trying to do it
class Foo
{
static int ReadSelfFromBase(void *userarg, int argc, char **argv, char **ColName){...}
public:
void Bar(sqlite3* db)
{
...
rc = sqlite3_exec(db, "select * from test", &ReadSelfFromBase, this, &zErrMsg);
...
}
}
int main()
{
Foo test;
...
test.Bar(db);
}
But callback doesn't call. If a do this
int main()
{
rc = sqlite3_exec(db, "select * from test", Foo::ReadSelfFromBase, NULL, &zErrMsg);
}
it all well. Does anybody know how solve this problem
PS Sorry for bad English
Since ReadSelfFromBase is a static function, Foo::ReadSelfFromBase should work the same in the Bar method as it does in main.
it's better to use Foo::ReadSelfFromBase any where you want, you know, it's static.
Related
I need to return a integer from callback, but I not succeeded.
I tried - but nothing.
I will be very glad if you will help me.
Here is my code:
using namespace std;
int main()
{
sqlite3* db;
char* zErrMsg;
sqlite3_open("try.db", &db);
//do something...
string query = "select * from myTable";
int *ptr;
sqlite3_exec(db, query.c_str(), callback, ptr, &zErrMsg);
cout << ptr << endl;
system ("pause");
return 0;
}
int callback(void* notUsed, int argc, char** argv, char** azCol)
{
/*
chane void* notUsed to int*
???how???
*/
return 0;
}
You have to pass an address of valid memory (e.g. on stack) or allocate it (heap) to the callback function, if you allocate you have to free it also.
The forth argument of the sqlite3_exec() function will be the first argument of the callback() function wich is of type void*. So if you pass the address of an int you have to interpret the void* as an int*.
I changed it so the memory (int someNumber) is in the callers function (main) and pass the address of it. In the callback function you need to cast the void* to the pointer type you expect, here int* and assign a value.
It should be:
...
int main()
{
...
int someNumber;
sqlite3_exec(db, query.c_str(), callback, &someNumber, &zErrMsg);
cout << someNumber << endl;
...
}
int callback(void* someNumberArg, int argc, char** argv, char** azCol)
{
int* someNumber = reinterpret_cast<int*> (someNumberArg);
*someNumber = 42;
return 0;
}
I am using visual studio 2015 and i want to use sqlite3 with it, i have managed to integrate sqlite3 into it, but i can only use it through native c style, i cannot use sqlite using classes as we do in c++. There is a table test in my database which contain values (id int , id1 int , name string)
For example this program runs fine
void forprinting(string a)
{
cout << a<<"\n";
}
int callback(void *NotUsed, int argc, char **argv, char **azColName) {
int i;
string testing;
string test2;
for (i = 0; i<argc; i++)
{
testing = testing + azColName[i];//irrelevant
test2 += argv[i];
}
forprinting(test2);
printf("\n");
return 0;
}
int main()
{
char *zErrMsg = 0;
sqlite3 *db;
int rc;
rc = sqlite3_open("DATA.db", &db);
char *data;
const char *sql;
sql = "SELECT * FROM test;";
sqlite3_exec(db, sql, callback, 0, &zErrMsg);
sqlite3_close(db);
system("pause");
return 0;
}
The output of this program is 0 0 test
which is fine but when i try to implement the same logic using classes i get the error here
#include <iostream>
#include <stdio.h>
using namespace std;
void forprinting(string a) {
cout << a << "\n";
}
class testingSqlite {
public :
int callback(void *NotUsed, int argc, char **argv, char **azColName) {
int i;
string testing;
string test2;
for (i = 0; i<argc; i++) {
testing = testing + azColName[i];
test2 += argv[i];
}
forprinting(test2);
printf("\n");
return 0;
}
void initiate() {
char *zErrMsg = 0;
sqlite3 *db;
int rc;
rc = sqlite3_open("DATA.db", &db);
char *data;
const char *sql;
sql = "SELECT * FROM test;";
sqlite3_exec(db, sql, callback, 0, &zErrMsg);
sqlite3_close(db);
}
};
int main()
{
testingSqlite test1;
test1.initiate();
system("pause");
return 0;
}
I know its a bad practice to define functions in class but i was in hurry. And it is giving
Error C3867 'testingSqlite::callback': non-standard syntax; use '&' to create a pointer to member
Error (active) argument of type "int (testingSqlite::*)(void *NotUsed, int argc, char **argv, char **azColName)" is incompatible with parameter of type "int (*)(void *, int, char **, char **)"
I tried to change the function arguments to fix it but nothing yet works.
This:
sqlite3_exec(db, sql, callback, 0, &zErrMsg);
Should be:
sqlite3_exec(db, sql, &testingSqlite::callback, 0, &zErrMsg);
The latter is the correct "member of" syntax. If you ever could use the former, it was nonstandard (some compilers did allow it).
That said, it won't work either because the function signature does not indicate it can be a member function.
Instead, you can use the "void *" of the parameter list.
That is, you must create something like
int callback(void *o, int argc, char **argv, char **cname)
{
testingSqlite op* = reinterpret_cast<testingSqlite *>(o);
return op->callback( argc, argv, cname );
}
This means your callback in tesingSqlite doesn't take the void *
You also provide c style callback as the function pointer, not your member function. You also must provide the 'this' pointer as the 4th parameter (it becomes the void * when it calls you back), like:
sqlite3_exec( db, sql, callback, this, &zErrMsg );
I am rather new to handle C callbacks in C++. I made a sqlite wrapper c++ class, which just calls sqlite3_exec().
static int callback(void *NotUsed, int argc, char **argv, char **azColName){
SqliteAccessor* sqlite = static_cast<SqliteAccessor*> NotUsed;
if(argc > 0) {
sqlite->set_table_exists(true);
}
return 0;
}
class SqliteAccessor{
public:
bool has_table(const string dbName, const string tblName)
{
string sql;
sql = "SELECT " + quote_string(tblName) + "FROM " + quote_string(dbName)
+ "WHERE type = 'table' AND name = " + quote_string(tblName) + ";";
char *zErrMsg = 0;
int rc = sqlite3_exec(m_db, sql.c_str(), callback, (void*) this, &zErrMsg);
if( rc != SQLITE_OK ){
printf("SQL error: %s", zErrMsg);
sqlite3_free(zErrMsg);
}
// anyway to return the result directly?
// return hasTable;
}
// can I avoid the following methods and the member variable?
void set_table_exists(bool isExist) { m_table_exist = isExist; }
bool get_table_exists() { return m_table_exist; }
private:
static bool m_table_exist;
};
int caller(){
SqliteAccessor sqlite;
// to check if table exist
if (sqlite->has_table()){
// will above work or
// I should do with an extra call to query the changed state?
}
}
Now, I am quite confused how the caller can get the result from sqlite wrapper. I think, the caller cannot have the result by simply calling has_table(), because the result is returned from the callback, by set_table_exists(). So shall the caller get the result by making another call, e.g. call sqlite->get_table_exists() ?
Then this implies for every callback, I need to make a member variable (also has to be static) in class SqliteAccessor, and a pair of set/get_state(), which will be very cumbersome.
How to design the class to make it nice to use by caller?
Unfortunately, our code base does not support c++11.
If you are on C++11 consider using a lambda instead of a callback.
class SqliteAccessor{
public:
bool has_table(const string dbName, const string tblName)
{
bool hasTable = false;
string sql;
sql = "SELECT " + quote_string(tblName) + "FROM " + quote_string(dbName)
+ "WHERE type = 'table' AND name = " + quote_string(tblName) + ";";
char *zErrMsg = 0;
int rc = sqlite3_exec(m_db, sql.c_str(), [&](void *NotUsed, int argc, char **argv, char **azColName){
SqliteAccessor* sqlite = static_cast<SqliteAccessor*> NotUsed;
if(argc > 0) {
hasTable = true;
}
}
, (void*) this, &zErrMsg);
if( rc != SQLITE_OK ){
printf("SQL error: %s", zErrMsg);
sqlite3_free(zErrMsg);
}
return hasTable;
}
};
If you don't have access to C++11, you can always manually write your functor. You lose a bit of conciseness and locality though. The nice part is that the functor can save the state you need.
struct callback{
bool operator(void *NotUsed, int argc, char **argv, char **azColName)
{
SqliteAccessor* sqlite = static_cast<SqliteAccessor*> NotUsed;
if(argc > 0) {
hasTable = true;
}
return false;
}
bool hasTable;
};
class SqliteAccessor{
public:
bool has_table(const string dbName, const string tblName)
{
bool hasTable = false;
string sql;
sql = "SELECT " + quote_string(tblName) + "FROM " + quote_string(dbName)
+ "WHERE type = 'table' AND name = " + quote_string(tblName) + ";";
char *zErrMsg = 0;
callback c;
int rc = sqlite3_exec(m_db, sql.c_str(), c, (void*) this, &zErrMsg);
if( rc != SQLITE_OK ){
printf("SQL error: %s", zErrMsg);
sqlite3_free(zErrMsg);
}
return c.hasTable;
}
};
The way I would do it is to make the callback a private static member function and basically do what you did. Like this:
class SqliteAccessor
{
public:
bool has_table(const std::string dbName, const std::string tblName);
private:
static int callback(void *NotUsed, int argc, char **argv, char **azColName);
bool m_hasTable;
};
int SqliteAccessor::callback(void *NotUsed, int argc, char **argv, char **azColName)
{
SqliteAccessor* sqlite = static_cast<SqliteAccessor*>(NotUsed);
if(argc > 0) sqlite->m_hasTable = true;
return 0;
}
bool SqliteAccessor::has_table(const std::string dbName, const std::string tblName)
{
m_hasTable = false;
string sql = "SELECT " + quote_string(tblName) + "FROM " + quote_string(dbName)
+ "WHERE type = 'table' AND name = " + quote_string(tblName) + ";";
char *zErrMsg = 0;
int rc = sqlite3_exec(m_db, sql.c_str(), callback, (void*) this, &zErrMsg);
if( rc != SQLITE_OK )
{
printf("SQL error: %s", zErrMsg);
sqlite3_free(zErrMsg);
}
return m_hasTable;
}
int caller()
{
SqliteAccessor sqlite;
// to check if table exist
if (sqlite.has_table())
{
// do stuff :)
}
}
If sqlite3_exec() does not work with static functions, you can try with a global function like this:
class SqliteAccessor
{
public:
bool has_table(const std::string dbName, const std::string tblName);
private:
bool m_hasTable;
friend int callback(void *NotUsed, int argc, char **argv, char **azColName);
};
int callback(void *NotUsed, int argc, char **argv, char **azColName)
{
SqliteAccessor* sqlite = static_cast<SqliteAccessor*>(NotUsed);
if(argc > 0) sqlite->m_hasTable = true;
return 0;
}
In c++, using sqlite3, a callback function is used to retrieve select results from the database:
rc = sqlite3_exec(db, query, callback, 0, &sqlErrorMsg);
With each record returned from the database this function is called:
static int callback(void *NotUsed, int argc, char **argv, char **azColName) {
int i;
std::cout << "Called\n";
for(i = 0;i < argc;i++) {
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
/** Example **/
//if(last) do something; //to demonstrate that I need access to this information inside of the callback
return 0;
}
I need a way to determine the last call to this function (on the last record of sql).
I assumed it would take some minds more experienced in c++. I'm still somewhat of a novice, so tips are always welcome. Thanks in advance.
Solution (with help from ):
rc = sqlite3_exec(db, sql, callback, (void*)rowCount, &zErrMsg);
Then in the callback
static callback(void* rowCount, int argc, char** argv, char** azColName) { //here the integer is converted to hex, but converting it is easy enough
}
As far as I can see, a pointer to structure can be used. But I am wondering, is there any more efficient or elegant way to do that? At least when a structure is being used, it is not easy to see what are the parameters used by the function.
Thanks for any insightful answer.
Here's a small example, that uses WIN32 API:
#include <windows.h>
#include <stdio.h>
struct PARAMS
{
int i;
char* msg;
};
DWORD WINAPI myThread(void* parameter)
{
PARAMS* params = (PARAMS*)parameter;
printf("Received parameters: i = %d, msg = '%s'\n", params->i, params->msg);
return 0;
}
int main(int argc, char* argv[])
{
char msg[] = "Hi there.";
PARAMS params;
params.i = 1;
params.msg = msg;
HANDLE threadHandle = CreateThread(NULL, 0, myThread, ¶ms, 0, NULL);
WaitForSingleObject(threadHandle, INFINITE);
return 0;
}
You say, that "it is not easy to see what are the parameters used by the function". Well it depends on situation. If you don't consider it "elegant" enough, you should leave some helpful comment there at least... if you are using good naming and trying to write code, that is self-documenting, then using of structure will be just fine.
Here's an example of wrapping CreateThread so that programmer that uses your code doesn't have to know that you are using some structure:
#include <windows.h>
#include <stdio.h>
class MyWrapper
{
private:
struct PARAMS
{
int i;
char* msg;
};
static DWORD WINAPI myThread(void* parameter)
{
PARAMS* params = (PARAMS*)parameter;
printf("Received parameters: i = %d, msg = '%s'\n", params->i, params->msg);
delete params;
return 0;
}
public:
HANDLE createThread(int i, char* msg)
{
PARAMS* params = new PARAMS;
params->i = i;
params->msg = msg;
return CreateThread(NULL, 0, MyWrapper::myThread, params, 0, NULL);
}
};
int main(int argc, char* argv[])
{
MyWrapper mw;
char msg[] = "Hi there.";
HANDLE threadHandle = mw.createThread(1, msg);
WaitForSingleObject(threadHandle, INFINITE);
return 0;
}
Here is a small example if you want to pass a single parameter to a thread function in Win32 API
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
DWORD WINAPI funHello(void *x)
{
int c = (int*)x;
printf("\n Thread No: %d\n",c);
// Do some work , call some function, etc.
return 0;
}
int main()
{
HANDLE myhandle;
DWORD threadId;
int c = 1;
myhandle = CreateThread(NULL, 0, funHello, (void *)c, 0, &threadId);
if (myhandle == NULL)
{
printf("Create Thread Failed. Error no: %d\n", GetLastError);
}
WaitForSingleObject(myhandle, INFINITE);
printf("\n Main Hello...\n");
CloseHandle(myhandle);
return 0;
}