Как привести void * к указателю на функцию? - PullRequest
0 голосов
/ 02 июля 2018

Я использую xTaskCreate во FreeRTOS, чей 4-й параметр (void * const) является параметром для передачи в функцию, вызванную новым потоком.

void __connect_to_foo(void * const task_params) {
   void (*on_connected)(void);
   on_connected = (void) (*task_params);
   on_connected();
}

void connect_to_foo(void (*on_connected)(void)) {
   // Start thread
   xTaskCreate(
         &__connect_to_foo,
         "ConnectTask",
         STACK_SIZE,
         (void*) on_connected, // params
         TASK_PRIORITY,
         NULL // Handle to the created Task - we don't need it.
         );
}

Мне нужно передать указатель на функцию с подписью

пустая полоса ();

Но я не могу понять, как привести void * к указателю на функцию, который я могу вызвать. Ближайшее, что я могу получить, это:

ошибка: 'void *' не является указателем на тип объекта в строке 3

Как я могу привести task_params к указателю на функцию, который я могу вызвать?

Обратите внимание: приведенный выше код значительно упрощен.

Ответы [ 2 ]

0 голосов
/ 02 июля 2018

Существует портативная альтернатива прямому приведению. Указатель на указатель функции сам по себе является указателем данных. То есть, учитывая, что auto connect_to_foo_ptr = &__connect_to_foo, void* ptr = &connect_to_foo_ptr везде допустимо.

Конечно, чтобы вызвать его, вам нужно привести void* обратно к void (**)(void * const task_params) и разыменовать его дважды. Первая разыменование возвращает вам указатель на функцию, вторая возвращает исходную функцию.

Одно из ограничений здесь заключается в том, что вам нужно убедиться, что connect_to_foo_ptr не выходит за рамки, но обычно это не проблема. Обычно вы можете сделать это static, но даже это не требуется для обычного шаблона обратного вызова.

0 голосов
/ 02 июля 2018

Что-то вроде этого:

typedef void (*OnConnected_t)();
OnConnected_t on_connected = OnConnected_t(task_params);
on_connected();
...