Envolviendo una función C que toma sus argumentos con void * en C ++ [duplicado]
Estoy envolviendo una función C de freeRTOS que crea una tarea y toma sus argumentos con un puntero vacío en C ++. La función se parece un poco a esto:
void createTask(TaskFunction_t taskCode, void * args);
Entonces, a mi entender, para pasar 2 argumentos a la tarea, necesitaría crear una estructura, convertir su dirección en void *, pasarla y luego devolverla al estado original así:
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));
}
¿Cuál sería la forma preferida de envolver esta función para poder pasar un número variable de argumentos de tipos de variables? ¿Debo dejar void * args como argumento o hay algo que se pueda hacer con plantillas o tal vez tuplas para simplificar un poco este proceso?
Respuestas
En C ++ 11 en adelante, puede usar algo como
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));
Debe asegurarse de que la vida útil de f
la tarea sea más larga (tal como lo haría con su Params
objeto).
En realidad, puede evitarlo por std::function
completo, ya que:
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)
Nuevamente, es realmente importante que f
permanezca vivo mientras dure su ejecución. No puedes ponerlo en una pila que muere antes de que lo haga la tarea.