标头中的EXPORT_SYMBOL导致“导出两次”错误

时间:2013-04-08 21:19:05

标签: c linux gcc linux-kernel c99

我有一个头文件,其中包含以下格式的几个全局变量的声明:

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 中的include guard是否应该阻止多次读取EXPORT_SYMBOL(var)

1 个答案:

答案 0 :(得分:3)

  

constants.h中的include guard不应该阻止   多次读取EXPORT_SYMBOL(var)?

include guard会阻止在相同源文件中多次包含标头。它不能阻止它通过多个源文件包含在内。请记住,所有来源的对象都会链接到一个对象中,从而导致冲突。

假设您有另一个头文件也包含在源文件中,名为foo.h,后者又包含constants.h。文件constants.c将尝试包括constants.h两次(一次直接通过constants.h再次通过foo.h)。 include guard在这里工作,而constants.h只包含一次。

foo.c也会发生同样的事情。它将尝试包括constants.h两次(一次直接通过constants.h再次通过foo.h)。包含守卫也在这里工作,constants.h只包含一次。

然后将两个对象constants.o和foo.o链接在一起,每个对象都通过constants.h与EXPORT的副本连接在一起。这最多可以增加两个。

您希望确保导出只出现在最终链接中一次。一种方法是将它们从常量文件(例如constants.h)中取出,然后将它们移动到名为exports.c的文件中。