Как я могу правильно назначить указатель на функцию обратного вызова?

#c #pointers #keil

Вопрос:

Я пытаюсь вызвать функцию в IRQ с помощью C, со следующим кодом я ее получаю.

 static void (*functionPulsacion)();  void eint2_init(void *funcPulsacion){  functionPulsacion = funcPulsacion; }  

Но когда я компилирую в Keil, IDE показывает мне следующее сообщение:

Button2.c(38): предупреждение: #513-D: значение типа «void *» не может быть присвоено сущности типа «void (*)()»

Каков наилучший способ сделать это?.

Заранее спасибо

Комментарии:

1. Параметр eint2_init должен иметь правильный тип указателя функции, а не просто void*

2. Задание не является неправильным. Это немного педантичное предупреждение. Но в этом случае я бы сказал, что разумно изменить определение функции на void eint2_init(void (*funcPulsacion)(void)){

Ответ №1:

Убедитесь funcPulsacion , что тип совпадает functionPulsacion с типом, например, так:

 static void (*functionPulsacion)(void);  void eint2_init(void (*funcPulsacion)(void)) {  functionPulsacion = funcPulsacion; }  

Это помогает typedef определить тип указателя функции, чтобы его можно было использовать повторно:

 typedef void (*functionPulsacion_type)(void);  static void functionPulsacion_type functionPulsacion;  void eint2_init(functionPulsacion_type funcPulsacion) {  functionPulsacion = funcPulsacion; }  

Комментарии:

1. Для полноты, вероятно, лучше также показать решение без typedef.

Ответ №2:

Для переменной параметра используется тот же синтаксис, что и для статической.

 static void (*functionPulsacion)(void);  void eint2_init(void (*funcPulsacion)(void)) {  functionPulsacion = funcPulsacion; }  

Однако символы ввода делают указатели функций намного более читабельными.

 typedef void (*PulsacionFunc)(void);  static PulsacionFunc pulsacion_func;  void eint2_init(PulsacionFunc a_pulsacion_func) {  pulsacion_func = a_pulsacion_func; }  

Ответ №3:

Это тип указателя на возвращаемую переменную функцию void .

 static void (*functionPulsacion)();  

Однако аргументом этой функции является void *

 void eint2_init(void *funcPulsacion){  functionPulsacion = funcPulsacion; }  

Забавно, что с любым указателем данных вы можете назначить a void * без каких-либо проблем

 void foo(void *vp) {  int *ip = vp; }  void bar(void *vp) {  char *cp = vp; }  

но в соответствии со стандартом, а не указателем на функцию

 void nope(void *vp) {  void (*fp)() = vp; // this might be a problem! }  

Любой указатель данных может быть приведен к a void * и обратно, даже без предупреждения. Но это указатели на данные, а не указатели на функции. Я верю, что POSIX говорит, что вы можете назначать указатели между void * и функциями, но стандарт C этого не делает.

Однако вы можете переключаться между указателями функций.

Конечно, это опасно, потому что, как только вы вызовете функцию, ей будет все равно, какой тип, по вашему мнению, у нее есть; она будет делать свое дело в соответствии с тем типом, который, как она знает, у нее есть. Поэтому здесь лучше всего просто использовать правильный тип указателя.

 void yeah(void (*arg)()) {  void (*fp)() = arg; }