如何在C中在运行时重新定义打印功能

时间:2015-12-01 20:21:23

标签: c printf

我目前正在使用简单的预处理器开关来禁用/启用我的调试语句。我将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。这可能吗?有没有更好的方法呢?

3 个答案:

答案 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);
}