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) が複数回読み取られるのを防ぐべきではありませんか?

インクルード ガードは、ヘッダーが同じソース ファイルに複数回インクルードされるのを防ぎます。複数のソースファイルを介して含まれることを防ぐことはできません。すべてのソースからのオブジェクトが 1 つのオブジェクトにリンクされるため、競合が発生することに注意してください。

foo.h という名前のソース ファイルにも含まれている別のヘッダーがあり、このヘッダーには constants.h が含まれているとします。ファイル constants.c は、constants.h を 2 回インクルードしようとします (1 回目は直接 constants.h を介して、もう 1 回は foo.h を介して)。インクルード ガードはここで機能し、constants.h は 1 回だけインクルードされます。

foo.c でも同じことが起こります。これは、constants.h を 2 回インクルードしようとします (1 回目は直接 constants.h 経由で、もう 1 回は foo.h 経由)。インクルード ガードはここでも機能し、constants.h は 1 回だけインクルードされます。

しかし、2 つのオブジェクト、constants.o と foo.o は一緒にリンクされ、それぞれがconstants.h を介して EXPORT の単一のコピーを持ちます。これは 2 つまで追加されます。

エクスポートが最終リンクに 1 回だけ表示されるようにする必要があります。これを行う 1 つの方法は、constants.h などの共通ファイルからそれらを取り出し、exports.c というファイルに移動することです。

于 2013-04-08T21:52:47.920 に答える