Avvolgere una funzione C che accetta i suoi argomenti con void * in C ++ [duplicato]
Sto avvolgendo una funzione C da freeRTOS che crea un'attività e prende i suoi argomenti con il puntatore void in C ++. La funzione assomiglia un po 'a questa:
void createTask(TaskFunction_t taskCode, void * args);
Quindi, per quanto ne so, per passare 2 argomenti all'attività avrei bisogno di creare una struttura, eseguire il cast del suo indirizzo su void *, passarlo e quindi restituirlo allo stato originale in questo modo:
struct Params
{
const int a;
const double b;
};
static void task(void * args)
{
auto params = *static_cast<Params*>(args);
// do something with params.a and params.b
}
int main()
{
Params params{1, 2.2};
createTask(task, static_cast<void*>(¶ms));
}
Quale sarebbe il modo preferito di avvolgere questa funzione in modo da poter passare un numero variabile di argomenti di tipi variabili? Dovrei lasciare void * args come argomento o c'è qualcosa che potrebbe essere fatto con modelli o forse tuple per semplificare un po 'questo processo.
Risposte
In C ++ 11 in poi, puoi usare qualcosa di simile
static void call_task(void *args) {
auto& f = *static_cast<std::function<void()>*>(args);
f();
}
// note: need this to stay alive!
std::function<void()> f = [&](){
// Any arguments you like here
do_whatever(1, 2, 3)
};
CreateTask(call_task, static_cast<void*>(&f));
Devi assicurarti che la durata di f
è più lunga di quella dell'attività (proprio come faresti per il tuo Params
oggetto).
Puoi effettivamente evitare del std::function
tutto, come:
template<typename Func>
void call_func(void *args) {
auto& f = *static_cast<Func*>(args);
f();
}
template<typename Func>
void wrapped_create_task(Func& func) {
CreateTask(call_func<Func>, static_cast<void*>(&func));
}
// you can still use `std::function` here, but you don't have to.
auto f = [&](){
// Any arguments you like here
do_whatever(1, 2, 3)
};
// this works on any object that implements `operator ()`
wrapped_create_task(f)
Ancora una volta, è davvero importante che f
rimanga in vita per tutta la durata della sua esecuzione. Non puoi metterlo su una pila che muore prima che il compito finisca.