peredozo
@peredozo

Как превратить void() в void (**)()?

Есть функция:
void btCallback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) {
	// ...
}

Которую надо передать сюда:
BT.register_callback(btCallback);

Компилятор ругается на это:
no known conversion for argument 1 from 'void(esp_spp_cb_event_t, esp_spp_cb_param_t*)' to 'void (**)(esp_spp_cb_event_t, esp_spp_cb_param_t*)'


Как я понимаю ему нужен pointer to function pointer, только как его передать не дорос, обычный function pointer (через &) ему тоже не нравится. Функция BT.register_callback от сторонней библиотеки, ее править не вариант.
  • Вопрос задан
  • 244 просмотра
Решения вопроса 2
@dima20155
you don't choose c++. It chooses you
Запишите указатель в переменную и отдайте адресс этой переменной.
Примерно так.
#include <iostream>

void bar(int n) {
    std::cout << (n*n) << std::endl;
}

void foo(void(**ptr)(int)) {
    (*ptr)(4);
    (*ptr)(40);
}

int main () {
    void(*c)(int);
    c = bar;
    foo(&c);
}


https://godbolt.org/z/heaWxPP7j
Ответ написан
@code_panik
UPD: Похоже, проблема в библиотеке
https://github.com/espressif/arduino-esp32/issues/7675
Исправляющий комит
https://github.com/espressif/arduino-esp32/commit/...

Довольно странное требование для api.
Если вы пишите класс-обертку над этой функцией, то она принимает просто функцию, а не указатель на указатель.
В C++ функция определяется своим адресом, и правила передачи функции в функцию похожи на правила передачи обычного массива.
Похоже, проблема именно в объявлении вашего register_callback, которое можно реализовать как в этом примере
#include <iostream>
using namespace std;

using esp_spp_cb_event_t = int;
using esp_spp_cb_param_t = void;

void btCallback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) {
    cout << "btCallback" << endl;
}

class MyBt {        
public:
    typedef void (*callback_type)(esp_spp_cb_event_t, esp_spp_cb_param_t *);    

    void register_callback(callback_type cb) {
        cb(0, nullptr);
    }
};

int main()
{    
    MyBt bt;
    bt.register_callback(btCallback);
    return 0;
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы