ошибка сегментации при доступе к переменным-членам с помощью функции обратного вызова - PullRequest
0 голосов
/ 05 июля 2010

У меня есть класс, в котором я объявляю статическую функцию. Я регистрирую эту функцию как функцию обратного вызова для другой библиотеки. Теперь внутри этой функции я разыменую данные обратного вызова на указатель класса и вызываю определенный нестатический член.

Вызов завершается успешно, и элемент управления переходит в нестатическую функцию-член. Но внутри этой функции в точке, где я получаю доступ к переменной-члену того же класса, я получаю ошибку сегментации. Это странно. Кто-нибудь может мне помочь с возможной ошибкой и решением?

Вот как выглядит код.

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

Ответы [ 3 ]

2 голосов
/ 05 июля 2010

Значение ptr, переданное callackwrapper, скорее всего, является недопустимым указателем или не является объектом класса test.Вызов все еще успешен, потому что, пока вы не обращаетесь к переменной-члену, метод класса такой же, как и обычная функция C ++.Вы получаете доступ к count, когда вы фактически разыменовываете объект, отсюда и ошибка сегментации.

2 голосов
/ 05 июля 2010

Прекратить использование void * s. У вас будет много неприятностей.

Скорее всего, вы вызываете callback () для недопустимого объекта. Я не могу судить по примеру, который вы привели, но мне так кажется. Мне нужно было бы убедиться в реализации registercallback (), но я отмечаю, что callbackwrapper () НЕ является статической функцией, и поэтому вызов ее, как если бы это была статическая функция (что, я подозреваю, может иметь место), вызовет всевозможные разрушения.

0 голосов
/ 05 июля 2010
int callbackwrapper(const char*a, const char *b, void *ptr)
{
  test *p = (test *)ptr; 
  p->callback(a, b);
}

является функцией-членом.Эта функция-член ищет ссылку на объект, которому она принадлежит.Таким образом, вышеприведенная функция выглядит примерно так:

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

Скорее всего, registercallback не ожидает здесь функцию-член.

Это можно решить, сделав callbackwrapper aстатическая функция-член:

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

Кроме того, не забывайте: если вы взаимодействуете с библиотекой C, и именно поэтому вам необходим обратный вызов, помните, что функции должны вызываться из Cнужно объявить extern "C", что заставит вас убрать эту функцию из класса и сделать ее

extern "C" int callbackwrapper(const char*a, const char *b, void *ptr)
{
  test *p = (test *)ptr; 
  p->callback(a, b);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...