【发布时间】:2023-11-17 04:33:01
【问题描述】:
我有一个头文件,其中声明了几个全局变量,格式如下:
constants.h
#ifndef CONSTANTS_H
#define CONSTANTS_H
extern unsigned var;
EXPORT_SYMBOL(var);
#endif
constants.c
#include "constants.h"
unsigned var = 10;
foo.c
#include "constants.h"
当我尝试编译内核模块时,每个导出的符号都会出现以下错误:
WARNING: /home/vilhelm/proj/constants: 'var' exported twice. Previous export was in /home/vilhelm/proj/foo.ko
我怀疑每次包含 constants.h 头文件时都会导出符号,但我不明白为什么。 constants.h 中的包含守卫不应该防止EXPORT_SYMBOL(var) 被多次读取吗?
【问题讨论】:
-
我认为您应该将 EXPORT_SYMBOL 宏移至 constants.c 文件。这样,您只需将其导出一次。请注意,每次包含标头时,它实际上都会将其复制粘贴到您的 c 文件中。如您所见,每次包含 constants.h 时,宏都会触发。
-
我意识到由于包含,它被多次触发,但我更想了解为什么包含保护不能阻止这种情况的发生。
-
当你编译这段代码时,你会创建两个目标文件。第一个是来自constants.h和constants.c的constants.o,第二个是由foo.c和constants.h创建的foo.o。现在,它们都导出符号 var。在链接方面,链接器看到 var 由 constants.o 和 foo.o 导出并发出警告。标头保护不能防止这种情况,因为问题发生在链接期间,而不是编译。
标签: c linux gcc linux-kernel c99