开发者

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);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜