Вы можете использовать переменную функцию, объявив сначала в списке параметров те параметры, которые всегда присутствуют, затем переменную часть.В следующем коде мы определяем тип для функций действия, void, возвращая в качестве параметра список аргументов:
typedef void (*action)(va_list);
Затем определяем общую процедуру действия, которая готовится к выполнению действия:
void try_this_action(char *szActionName, int trials, action fn_action, ...)
{
va_list args;
va_start(args, fn_action); //Init the argument list
DEBUG_PRINT(szActionName); // This line changes
uint8_t attempts = 0;
uint8_t max_attempts = trials; // max_attempts changes
//Here we call our function through the pointer passed as argument
while (!fn_action(args) && attempts < max_attempts)
{ // This line changes
attempts++;
DEBUG_PRINT(".");
if (attempts == max_attempts)
{
DEBUG_PRINTLN(" - Failed.");
soft_reset(); // Start all over again
}
delay(100);
}
DEBUG_PRINTLN(" - Success");
wdt_reset(); // Reset watchdog timer, ready for next action
va_end(args);
}
Каждая функция должна быть закодирована для использования списка аргументов:
int power(va_list args)
{
//First recover all our arguments using the va_arg macro
bool cond = va_arg(args, bool);
if (cond == true)
{
... //do something
return true;
}
return false;
}
Использование будет:
try_this_action("Powering ON", 3, module.power, true);
try_this_action("Waiting for signal", 10, module.signal);
try_this_action("Sending SMS", 3, module.sendSMS, "test");
try_this_action("Powering OFF", 1, module.power, false);
Если вам нужна дополнительная информация о функциях с переменными числами и использовании макросов stdarg.hГугл в сети.Начните отсюда https://en.cppreference.com/w/c/variadic.
Это может быть закодировано также как реализация макроса, как отличное предложение в ответе Джона Боллинджера, но в этом случае вы должны учитывать, что каждое использование макроса будет создавать весь код, чтов конечном итоге может быть даже лучше для скорости (избегая вызова функции), но может не подходить для систем с ограниченной памятью (встроенной) или для тех случаев, когда вам нужна ссылка на функцию try_this_action
(не существует).