Я использую C ++ на ESP-32. При регистрации таймера я должен сделать это:
timer_args.callback = reinterpret_cast<esp_timer_cb_t>(&SoundMixer::soundCallback);
timer_args.arg = this;
Здесь таймер звонит soundCallback
.
И то же самое при регистрации задачи:
xTaskCreate(reinterpret_cast<TaskFunction_t>(&SoundProviderTask::taskProviderCode), "SProvTask", stackSize, this, 10, &taskHandle);
Таким образом, метод запускается в отдельной задаче.
GCC всегда предупреждает меня об этих преобразованиях, но работает так, как и планировалось.
Это приемлемо в производственном коде? Есть лучший способ это сделать?
std::bind
Также не принимает указатель объекта в качестве первого аргумента метода?extern "C"
здесь? Важна ли в этом случае связь С?__attribute__((cdecl))
, но не делайте этого). В противном случае функция C ++ не будет иметь C-совместимого соглашения о вызовах (хотя в GCC это обычно работает нормально).extern "C"
это формально необходимо, см.[dcl.link]
«Два типа функций с различными языковыми связями являются разными типами, даже если они в остальном идентичны». и[expr.call]
«Вызов функции через выражение, тип функции которого отличается от типа функции определения вызываемой функции, приводит к неопределенному поведению»Лично, самый совместимый, простой в реализации и понятный подход, который я нашел, - это просто предоставить функцию-обертку, совместимую с ожидаемым интерфейсом C, которая внутренне вызывает метод (и, в случае, если он не статичен, создать экземпляр или использовать существующий экземпляр для этого). Это можно рассматривать как разновидность шаблона проектирования адаптера.
источник
static
я увидел его как метод и по какой-то причине не осознал, что он не передаетthis
указатель в качестве первого аргумента (и последующие дебаты об использовании егоstd::bind
усиливают). Но да, вы абсолютно правы! (Извините за двойной ответ!)static
имеет как минимум три разных значения. И вы их перепутаете, если не будете осторожны. Я бы сказал, что действительно полезно понимать различия между различными видами использованияstatic
, поскольку каждый из них является отличным инструментом сам по себе.