I have a static method inside my class, which I use for a callback.
Inside this callback I want to add a value to result.
This seems not to be possible because of the recast(?).
Is there a way to access the member variable result and add values to it after recasting, or do I need to think of a different way?
MyClass.h
class MyClass
{
public:
vector<string> result;
static int c_CB(void *data, int argc, char **argv, char **azColName);
int Callback(int argc, char **argv, char **azColName);
void Do(string query);
}
MyClass.cpp
void MyClass:Do(string query)
{
sqlite3_exec(this->dbResource, query.c_str(), this->c_CB , NULL, &this->errorMsg);
}
int MyClass::c_CB(void *NotUsed, int argc, char **argv, char **azColName)
{
MyClass* bar = reinterpret_cast<MyClass*>(NotUsed);
// after reinterpret cast, it does not work
//bar->result.insert(bar->result.end(), "foo");
// function call works
return bar->Callback(argc, argv, azColName);
}
int MyClass::Callback(int argc, char **argv, char **azColName)
{
cout << "working" << endl;
}
main.cpp
int main()
{
MyClass* cl = new MyClass();
cl->Do("something");
}
The documentation states that the fourth argument to sqlite3_exec is passed as the first argument of the callback.
Currently you are passing NULL, which you then cast to a MyClass* and attempt access the object, which results in undefined behaviour.
Use this as the fourth argument in place of NULL.
It seems you are trying to access a non-static member function from a static member callback function c_CB.
You were able to call a member function Callback but nothing from the class is accessible, but if I'm correct, the compiler just interpreted Callback as a static function.
If you actually breakpoint inside this function, you can see that none of your member variables actually have a memory address. And the current class, this is null
I'm not sure if the cout << statement still works or if its causing the problem
This is a possible solution to your issue, although it may not be the best one.
class MyClass
{
public:
vector<string> result;
static int c_CB(void *data, int argc, char **argv, char **azColName);
int Callback(int argc, char **argv, char **azColName);
void Do(string query);
void MemberFunction()
{
cout << "working" << endl;
}
static MyClass* currentClass; //Add a static class pointer and assign your class address to it before firing the callback.
}
MyClass* MyClass::currentClass = NULL;
void MyClass:Do(string query)
{
sqlite3_exec(this->dbResource, query.c_str(), this->c_CB , NULL, &this->errorMsg);
}
int MyClass::c_CB(void *NotUsed, int argc, char **argv, char **azColName)
{
MyClass* bar = reinterpret_cast<MyClass*>(NotUsed);
// after reinterpret cast, it does not work
//bar->result.insert(bar->result.end(), "foo");
// function call works
return bar->Callback(argc, argv, azColName);
}
int MyClass::Callback(int argc, char **argv, char **azColName)
{
currentClass->MemberFunction();
}
int main()
{
MyClass* cl = new MyClass();
MyClass::currentClass = this;
cl->Do("something");
}
Related
Why my compiler(GCC) doesnt implicitly cast from char** to const char**?
Thie following code:
#include <iostream>
void print(const char** thing) {
std::cout << thing[0] << std::endl;
}
int main(int argc, char** argv) {
print(argv);
}
Gives the following error:
oi.cpp: In function ‘int main(int, char**)’:
oi.cpp:8:12: error: invalid conversion from ‘char**’ to ‘const char**’ [-fpermissive]
oi.cpp:3:6: error: initializing argument 1 of ‘void print(const char**)’ [-fpermissive]
Such a conversion would allow you to put a const char* into your array of char*, which would be unsafe. In print you could do:
thing[0] = "abc";
Now argv[0] would point to a string literal that cannot be modified, while main expects it to be non-const (char*). So for type safety this conversion is not allowed.
#Fred Overflow's link to the FAQ is a complete answer. But (sorry Marshall) it's not the most clear explanation. I don't know if mine is more clear, but I hope so.
The thing is, if p is a char* pointer, then it can be used to modify whatever it's pointing at.
And if you could obtain a pointer pp that points to p, but with pp of type char const**, then you could use pp to assign to p the address of a const char.
And with that, you could then use p to modify the const char. Or, you would think you could. But that const char could even be in read-only memory…
In code:
char const c = 'a';
char* p = 0;
char const** pp = &p; // Not allowed. :-)
*pp = &c; // p now points to c.
*p = 'b'; // Uh oh.
As a practical solution to your code that does not compile, …
#include <iostream>
void print(const char** thing) {
std::cout << thing[0] << std::endl;
}
int main(int argc, char** argv) {
print(argv); // Dang, doesn't compile!
}
just do …
#include <iostream>
void print( char const* const* thing )
{
std::cout << thing[0] << std::endl;
}
int main( int argc, char** argv )
{
print( argv ); // OK. :-)
}
Cheers & hth.,
Note, that although
void dosmth(const char** thing);
int main(int argc, char** argv) {
dosmth(argv);
is forbidden, you can and should do
void dosmth(const char* const* thing);
int main(int argc, char** argv) {
dosmth(argv);
Which is probably what you wanted anyway. The point here is that thing now refers to a const char* array which is itself immutable and which referenced values char are themselves immutable.
So, for a "look at it, but do not change it" scenario, const char* const* is the type to use.
Note: I used the more common (but in my opinion inferior) standard of trying to write the const modifier as left as possible. Personally, I recommend writing char const* const* instead of const char* const* as it is hugely more concise that way.
Because it might allow us to modify a constant value. Read here to understand why: http://c-faq.com/ansi/constmismatch.html
I’m trying to make the SQLite callback function part of my class. Any examples? I have tried this but it isn't compiling:
class Customer
{
...
public:
int callback(void* data, int argc, char **argv, char **azColName);
};
std::string Customer::getCustomer()
{
...
int res = sqlite3_exec(db, sqlStatement.c_str(), callback, nullptr, &errMessage);
...
}
The problem is with callback parameter in sqlite3_exec.
You should use static method for sqlite3_exec as a callback.
define:
static int callback(void* data, int argc, char **argv, char **azColName);
call:
int res = sqlite3_exec(db, sqlStatement.c_str(), Customer::callback, nullptr, &errMessage);
I want to read argv[1] as char* so this is what I do
using namespace std;
const char *myarg = NULL;
void Plots(char* file);
int main( int size_t argc, char* argv[] ) {
myarg = argv[1];
cout<<" this is a test "<<argv[1]<<endl;
Plots(argv);
}
void Plots(char* fileList){
cout<< argument passed correctly "<<endl;
}
}
However, when executing I get
Error: Function Plot() is not defined in current scope :0:
argv is a char *[], which for all practical purposes is char **.
You declared
void Plots(char * file);
The parameter to Plots() is a char *.
Plots(argv);
This attempts to pass a char ** to a function that takes char * as a parameter.
Additionally, although you declared
void Plots(char * file);
but then you went ahead and defined
void Plot(char* fileList)
Furthermore:
cout<< argument passed correctly "<<endl;
There's a quote missing here.
So, there's three different bugs here.
I built an interface taking pointers to functions. Sometimes this calculation depends on state, which I want to encapsulate in a class and pass its method:
#include <iostream>
class Printer {
public:
static void print(int i) { // Want to get rid of the static
std::cout << i << "\n";
}
};
template<typename int_func>
void with_1(int_func func) {
func(1);
}
int main(int argc, char const *argv[]) {
Printer printer;
with_1(printer.print);
return 0;
}
I need non-static methods (and would even prefer overloading operator()). However removing the static results in error: a pointer to a bound function may only be used to call the function.
I could use a dummy like this:
Printer printer;
void dummy(int i) {
printer.print(i);
}
int main(int argc, char const *argv[]) {
with_1(dummy);
return 0;
}
But that does not look elegant to me. Can I write a template that accepts both, function pointers and non-static methods? Or is there even a better design pattern for my problem?
You can not simply pass non-static method like this, because they work on instance. A simply solution is to use lambda:
#include <iostream>
class Printer {
public:
static void print(int i) { // Want to get rid of the static
std::cout << i << "\n";
}
};
template<typename int_func>
void with_1(int_func func) {
func(1);
}
int main(int argc, char const *argv[]) {
Printer printer;
// Can use capture by reference because we are sure printer still
// exist during execution of with_1
with_1([&printer](int i){ printer.print(i); });
return 0;
}
example
Try this:
int main(int argc, char const *argv[]) {
Printer printer;
with_1( std::bind( &Printer::print, printer, std::placeholders::_1 ) );
return 0;
}
(You'll need to #include <functional>.)
Simple question, how can I run a program having main inside a class?
I have a code:
MojSwiat2.cpp:
int Main::main() {
// code
return 0;
}
And MojSwiat2.h:
class Main {
public:
int main();
};
Main run;
int Main::main() { // with this I have error: function int Main::main(void) already has a body
run.main();
} // and without I got unresolved external symbol _main referenced in function __tmainCRTStartup
Reason I need to do this: Accessing protected members of class from main
By defining a normal main that only contains a call to your other function. Like this:
int main(int, char**) {
return Main().main();
}
int main(int argc, char* argv[])
{
Main m;
return m.main();
}
or if Main::main is declared static
int main(int argc, char* argv[])
{
return Main::main();
}
You still need to define main.
class my_app {
int main(int argc, char* argv[])
{
// ...
}
}
my_app app;
int main(int argc, char *argv[])
{
return app.main(argc, argv);
}