Реализация функций обратного вызова в C - PullRequest
5 голосов
/ 29 апреля 2010

Я новичок в C. Я пытаюсь реализовать функцию обратного вызова, используя указатели функций.

Я получаю ошибку

:test_callback.c:10: error: expected identifier or ‘(’ before ‘void’

когда я пытаюсь скомпилировать следующую программу:

#include<stdio.h>

void (*callback) (void);

void callback_proc ()
{
  printf ("Inside callback function\n");
}

void register ((void (*callback) (void)))
{
  printf ("Inside registration \n");
  callback (); /* Calling an initial callback with function pointer */
}

int main ()
{
  callback = callback_proc;/* Assigning function to the function pointer */
  register (callback);/* Passing the function pointer */
  return 0;
}

Что это за ошибка? Может кто-нибудь помочь?

Ответы [ 6 ]

19 голосов
/ 29 апреля 2010
  1. register - ключевое слово C: используйте другое имя для функции.

  2. У вас есть дополнительные паратезы вокруг параметра обратного вызова. Должно быть:

    void funcName(void (*callback) (void))
    
3 голосов
/ 29 апреля 2010

Я бы порекомендовал использовать typedef

#include<stdio.h>

typedef void (*callback_t) (void);
callback_t callback;

void callback_proc(void)
{
    printf ("Inside callback function\n");
}

void reg( callback_t _callback )
{
    printf ("Inside registration \n");
    _callback();
}

int main ()
{
    callback = callback_proc;
    reg(callback);

    return 0;
}

РЕДАКТИРОВАТЬ: удален вопрос реестра

2 голосов
/ 29 апреля 2010

Вы не можете использовать 'register' в качестве имени функции, так как это ключевое слово C.

0 голосов
/ 29 апреля 2010
#include<stdio.h>

typedef void (*callback_func) (void);

static callback_func the_callback = 0;

void process (void)
{
  printf ("Inside process function\n");
}

void callback_register (callback_func cb)
{
  the_callback = cb;
  printf ("Inside registration \n");
}

void callback(void)
{
    the_callback();
}

int main (void)
{
  callback_register(process); /* Passing the function pointer */
  callback();
  return 0;
}

Объявление the_callback статического имело бы больше смысла, если бы этот код был модульным, и тогда вам пришлось бы вызывать callback_register для его установки и callback для его вызова - the_callback не было бы доступны за пределами реализации (.c) только заголовки функций будут в заголовке (.h).

0 голосов
/ 29 апреля 2010

Посмотрите на безопасные обратные вызовы типа из ccan . Одно дело выставить указатель на типизированную функцию для всего мира, другое - обеспечить правильное приведение.

0 голосов
/ 29 апреля 2010

2 задачи:

  • вы не можете использовать имя register, поскольку это ключевое слово (больше не используется, но оно все еще там)
  • изменить определение функции с

    void wasRegister((void (*callback) (void)))
    

    до:

    void wasRegister(void (*callback) (void))
    

    (избавиться от скобок вокруг объявления параметра.

Также вы можете получить предупреждение о том, что callback_proc() не соответствует задержке для переменной callback (в зависимости от того, как вы компилируете программу - как C или C ++), поэтому вы можете изменить ее объявление на:

void callback_proc (void)

, чтобы сделать явным, что он не принимает параметров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...