简体   繁体   English

使用回调函数访问成员变量时出现分段错误

[英]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 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);
   }
}

Stop using void*s. 停止使用void * s。 You will get yourself into a lot of trouble. 您会遇到很多麻烦。

Chances are you're calling callback() on an invalid object. 您可能在无效对象上调用callback()。 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. 我需要确保看到registercallback()的实现,但是我注意到callbackwrapper()不是静态函数,因此像调用静态函数一样调用它(我怀疑可能是这样)各种各样的破坏。

The ptr passed to callackwrapper is most likely an invalid pointer or not an object of the class test . 传递给callackwrapperptr很可能是无效的指针,或者不是类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. 调用仍然成功,因为只要您不访问成员变量,类方法就与普通的C ++函数相同。 Where you access count is when you actually dereference the object, hence the segmentation fault. 访问count是实际取消引用对象的时间,因此存在分段错误。

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. 最有可能的registercallback在这里不期望成员函数。

You can solve this by making callbackwrapper a static member function: 您可以通过使callbackwrapper成为静态成员函数来解决此问题:

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 另外,请不要忘记:如果要与C库连接,这就是需要回调的原因,请记住,要从C调用的函数需要声明为extern "C" ,这将迫使您将该功能移出类,并使其完成

extern "C" int callbackwrapper(const char*a, const char *b, void *ptr)
{
  test *p = (test *)ptr; 
  p->callback(a, b);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM