segmentation fault when i access member variables using a callback function
I have a class, in which i declare a static function. I register this function as the callback function for another library. Now, inside this function, i dereference the callback data to the class pointer and invoke a particular non-static member.
The invocation succeeds and the control comes into the non-static member function. But inside this function at the point where i access a member variable of 开发者_Python百科the same class, i get a segmentation fault. This is strange. Can anybody help me with the possible mistake i have made and the solution?
Here is how the code looks like.
class test
{
int count;
int callback(const char * a, const char *b)
{
print(a);
print(b);
count++; //// HERE IS WHERE I GET THE SEGMENTATION FAULT
}
public:
static int callbackwrapper(const char*a, const char *b, void *ptr)
{
test *p = (test *)ptr;
p->callback(a, b);
}
test():count(0) {}
~test() {}
Register()
{
registercallback(callbackwrapper);
}
}
The ptr
passed to callackwrapper
is most likely an invalid pointer or not an object of the class test
. The invocation still succeeds because as long as you don't access a member variable, a class method is the same as a normal C++ function. Where you access count
is when you actually dereference the object, hence the segmentation fault.
Stop using void*s. You will get yourself into a lot of trouble.
Chances are you're calling callback() on an invalid object. I can't tell from the example you gave, but that's what it seems like to me. I would need to see registercallback()'s implementation to be sure, but I note that callbackwrapper() is NOT a static function, and therefore calling it as if it were a static function (which I suspect may be the case) will wreak all sorts of havoc.
int callbackwrapper(const char*a, const char *b, void *ptr)
{
test *p = (test *)ptr;
p->callback(a, b);
}
is a member function. That member function is looking for a reference to the object to which it belongs. That is, the function above becomes something like this under the covers:
int callbackwrapper(test* this, const char*a, const char *b, void *ptr)
{
test *p = (test *)ptr;
p->callback(a, b);
}
Most likely registercallback is not expecting a member function here.
You can solve this by making callbackwrapper
a static member function:
static int callbackwrapper(const char*a, const char *b, void *ptr)
{
test *p = (test *)ptr;
p->callback(a, b);
}
Also, don't forget: If you are interfacing with a C library, and that's why you're needing the callback, do keep in mind that functions to be called from C need to be declared extern "C"
, which would force you to move that function out of the class, and make it
extern "C" int callbackwrapper(const char*a, const char *b, void *ptr)
{
test *p = (test *)ptr;
p->callback(a, b);
}
精彩评论