2010-04-29 6 views
5

Я новичок C. Я пытаюсь реализовать функцию обратного вызова с помощью указателей функций.Реализация функций обратного вызова в 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; 
} 

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

+0

'register' - ключевое слово, BTW. –

+0

В какой строке вы видите ошибку? –

+0

Просто подсказка: typedefs помогают сделать вещи более читабельными: 'typedef void (* CallbackFunc) (void);'. Тогда ваша сигнатура функции - 'void registerFunc (callbackFunc callback)', и ваши объявления - 'CallbackFunc my_cb = & callback_proc' – detly

ответ

3

Я бы рекомендовал использовать ЬурейеЕ

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

EDIT: убрана вопрос регистра

+1

где typedef? это очень хорошая рекомендация, но ваш пример ее отсутствует. –

+0

Я не вижу typedef? То, что вы сделали, определяется указателем на функцию, который не является безопасным для типа. –

+0

Извините, не понял, что у меня возникла проблема с копией и вставкой. – stacker

2

Вы не можете использовать «регистрация» в качестве имени функции, как это C ключевое слово.

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

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

    void funcName(void (*callback) (void)) 
    
+0

Да, дополнительные парнеры были трудно поймать. +1 –

0

2 проблемы:

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

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

    до:

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

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

Кроме того, вы можете получить предупреждение о callback_proc() не имеющие соответствия delaration к переменной callback (в зависимости от того, как скомпилировать программу - как C или C++), так что вы можете захотеть изменить свою декларацию:

void callback_proc (void) 

, чтобы уточнить, что он не принимает никаких параметров.

0

Посмотрите на type safe callbacks от ccan. Его одна вещь, чтобы разоблачить типизированный указатель функции для использования в мире, а другой - для обеспечения разумного литья.

+1

Привет, Тим, ссылка в вашем ответе мертва. – bummi

+0

@bummi, если Тим решает удалить этот ответ, он получит сообщение * Это сообщение было удалено Tim Post ♦. Чтобы узнать, почему ваш ответ был удален, используйте meta *: D –

0
#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

большое спасибо ... я мог понять мои ошибки – user329013

Смежные вопросы