我目前正在使用简单的预处理器开关来禁用/启用我的调试语句。我将printf重定向到UART输出,然后在全局包含的头文件(globals.h)中定义我的print函数,以便轻松禁用所有调试:
#ifdef USE_UART
#define MY_PRINT(...) printf(__VA_ARGS__)
#else
#define MY_PRINT(...)
#endif
然后我的所有应用程序文件都可以通过UART打印调试消息,如下所示:
MY_PRINT("\t<<Battery Voltage: %d>>\r\n", vBat);
我尝试做的是在运行时通过外部输入(即按下按钮)切换。例如:
void my_print(const char * pString){
if (uart_mode == UART_ON){
printf(pString);
}
}
可以通过外部输入切换uart_mode。我无法弄清楚如何通过此函数将变量参数正确地传递给printf。这可能吗?有没有更好的方法呢?
答案 0 :(得分:3)
这样的事情怎么样:
#define MY_PRINT(...) \
do { \
if (uart_mode == UART_ON) \
printf(__VA_ARGS__); \
} while(0)
答案 1 :(得分:2)
一种在运行时避免条件的好方法(虽然它仍然是动态调度)并且精确地模拟函数调用(因为它是一个函数调用)将是:
typedef int (*printf_func_t)(const char *, ...);
int dummy_printf(const char *format, ...) {
return 0;
}
/* Set initial value based on initial uart_mode */
printf_func_t dynamic_printf = uart_mode == UART_ON ? &printf : &dummy_printf;
在其他一些切换代码中(其中uart_mode
已更改),您只需测试并重新分配:
dynamic_printf = uart_mode == UART_ON ? &printf : &dummy_printf;
然后,实际用户总是调用dynamic_printf
代替printf
,并调用当前分配给函数指针的函数。打印时不会发生uart_mode
的读取或测试,它只会调用当时发现的任何功能。
答案 2 :(得分:0)
正如大卫施瓦茨所说,这是vprintf
的用途。
#include <stdarg.h>
void my_print(const char * pString, ...){
va_list args;
va_start(arg, pString);
if (uart_mode == UART_ON){
vprintf(pString, args);
}
va_end(args);
}