2017-08-01 41 views
0

私はdbinfo.h vizの簡単な構造を持っています。私はリンクしようとすると、私はC言語の関数間でデータ値を共有する

#include "dbinfo.h" 
extern dbinfo *tst_info; 

int getnumflds() { 

    return tst_info.fields; 
} 

私がUtilities.cの中に未定義のシンボルを取得している他のファイルUtilities.cので

#include <string.h> 
... 
#include "dbinfo.h" 
extern dbinfo *tst_info; 

void main() { 

tst_info = (dbinfo *) calloc(1, sizeof(dbinfo)); 

dbinfo.fields = 3; 

printf("\n number of fields = %d"), getnumflds()); 
... 
} 

:私は、メインプログラムで

typedef struct { 
    int fields; 
} dbinfo; 

tst_info。 externを削除した場合、未解決のシンボルはありませんが、フィールドの値は0です。

ここで何が間違っていますか?

私は、別にコンパイルされた他の関数でmainに設定された 'fields'の値を使い、変更できるようにしたいだけです。

私はCを使用しており、これらのニューロンにアクセスするのに時間がかかりました。

+2

正確に、もう少しを伝えるために。 Externは "変数はelsewereコンパイラで、私を信頼している"とだけ伝えます。しかし、実際には決して作成しないので、リンカーはそれを見つけられません。 ファイルの1つからexternを削除するだけです。 –

+0

わかりません。メインプログラムでは、それをexternと指定して割り当てます。 –

+0

メインプログラムからexternを削除し、サブルーチンの 'fields'を参照すると、メインプログラムで3に設定してもゼロになります。 –

答えて

2

すべての定義がextern以外)である必要があります。特定のオブジェクトファイル内の変数のexternキーワードは、変数の格納場所が他のオブジェクトファイルで提供されるため、リンカーにデータ領域内の領域の割り当てを控えるよう指示します。すべてのオブジェクトファイルで変数がexternと定義されている場合は、そのオブジェクトファイルにストレージを提供するオブジェクトファイルはありません。

あなたは、この記事で扱うことができるよりも、この詳細を読むことができます: https://stackoverflow.com/a/1433387/773113

+0

詳細:「1を除くエクスターナルでなければならない」少しオーバーステート。 'extern int foo; int foo; int foo = 5; 'は' int foo; 'が暫定的な定義であるため有効です。 – chux

+0

@chux本当ですが、私はどのように私が過度の記述を避けることができないと同時に、移植性が低く、それゆえ望ましくない練習を提案することを控えることはできません。 –

1

tst_infoは、両方の翻訳単位でexternと宣言しています。 externというキーワードは、extern翻訳の一部で、別の場所で使用できることを意味します。実際にはではなく、externキーワードを持つで定義し、その代わりに初期値(calloc、またはNULLなど)の値を設定する必要があります。

プログラムの使用状況に応じて、dbinfo *の代わりにグローバルdbinfoを宣言する方が簡単な場合もあります。ダイナミックなランタイムアロケーションから移動できるデータが多くなればなるほど、より良いものになります。

関連する問題