5

我尝试使用命令 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?

4

3 回答 3

5

KERN_INFO定义为字符串常量“\001”“6”。写的时候

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

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

"\001" "6" "Hello %s!"

到单个字符串常量。但是,这不适用于变量,如下所示buf

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

起作用的是:

char buf[] = KERN_INFO "Hello %s!";
printk(buf, "WORLD");
于 2019-01-29T22:46:33.237 回答
2

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

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

于 2019-01-29T22:46:19.063 回答
0

使用三个组件的可能解决方法:一个可以生成具有特定日志级别的调试函数的宏,使用所需的日志级别创建此函数,另一个宏调用具有可变数量参数的创建函数。
调用 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__)
于 2020-09-28T15:51:29.643 回答