2

我有一个头文件,其中声明了几个全局变量,格式如下:

常量.h

#ifndef CONSTANTS_H
#define CONSTANTS_H

extern unsigned var;
EXPORT_SYMBOL(var);

#endif

常量.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)被多次读取吗?

4

1 回答 1

3

constants.h 中的包含保护不应该阻止 EXPORT_SYMBOL(var) 被多次读取吗?

包含保护防止标头在同一个源文件中多次包含。它不能阻止它通过多个源文件被包含。请记住,来自所有来源的对象都链接到一个对象中,因此会产生冲突。

假设您有另一个头文件,它也包含在源文件中,称为 foo.h,它又包含 constants.h。文件 constants.c 将尝试包含 constants.h 两次(一次直接通过 constants.h,另一次通过 foo.h)。include 守卫在这里工作,constants.h 只会被包含一次。

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

但是随后这两个对象,constants.o 和 foo.o 将被链接在一起,每个对象都通过 constants.h 拥有其EXPORT 的单个副本。这加起来是两个。

您要确保导出仅在最终链接中出现一次。一种方法是将它们从常量.h 之类的公共文件中取出,并将它们移动到名为exports.c 的文件中。

于 2013-04-08T21:52:47.920 回答