C语言 如何在 printk 中使用变量作为格式字符串



我尝试使用命令printk。

我可以在互联网上找到的所有示例都是直接在 printk 中放置一个字符串,如下所示:

printk(KERN_INFO "Hello %s!", "World");

但是,我尝试使用如下缓冲区替换"Hello %s!":

char buf[] = "Hello %s!";
printk(KERN_INFO buf, "WORLD");

原来我收到了错误

error: expected ')' before 'buf'

我们应该怎么做才能在printk中使用变量并使用日志级别KERN_INFO?

KERN_INFO定义为字符串常量"\001"6"。写作时

printk(KERN_INFO "Hello %s!", "World");
C

编译器根据 C 标准的要求自动连接三个字符串常量:

"01" "6" "Hello %s!"

到单个字符串常量。但是,这不适用于变量,就像buf在这里一样:

char buf[] = "Hello %s!";
printk(KERN_INFO buf, "WORLD");

有效的是:

char buf[] = KERN_INFO "Hello %s!";
printk(buf, "WORLD");

KERN_INFO是在 Linux 内核标头中定义的宏,当预处理器运行时,它会扩展为字符串文本。在 C 代码中相邻放置字符串文字时,它们会隐式连接;在字符串文本之间放置变量时,这是语法错误。

如果将代码预处理到文件,则会更容易观察到这一点。

具有三个组件的可能解决方法:一个可以生成具有特定日志级别的调试函数的宏,使用所需的日志级别创建此函数,另一个宏调用具有可变数量的参数的创建函数.
调用 LOGPRINTK(buf,"WORLD")即可完成这项工作。

#include "stdarg.h"
// a macro which can generate a loglevelfunction based on the loglevel
// in kzalloc, do not forget the + 1 for the trailing zero
#define GENERATE_LOGLEVEL_FUNCTION(loglevelstring) void loglevelfunc(char *fmt, ...) { 
   char *modifiedfmt = NULL; 
   va_list input; 
   modifiedfmt = kzalloc((strlen(loglevelstring) + strlen(fmt) + 1 )*sizeof(char), GFP_KERNEL) ; 
   if (modifiedfmt) { 
      strcpy(modifiedfmt, loglevelstring); 
      va_start(input, fmt); 
      strcat(modifiedfmt, fmt); 
      vprintk(modifiedfmt, input) ; 
      va_end(input); 
      kfree(modifiedfmt); 
      modifiedfmt = NULL; 
    } 
}
// this line generates the log level function, with loglevel KERN_INFO
GENERATE_LOGLEVEL_FUNCTION(KERN_INFO)
// finally, the function we want
#define LOGPRINTK(...) loglevelfunc(__VA_ARGS__)

相关内容

  • 没有找到相关文章

最新更新