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