2016-07-01 17 views
2

私はCプログラムを使用するためのC++共有ライブラリを作成しています。しかし、externextern "C"について質問があります。変数のexternとextern "C"

私のヘッダファイルは次のようである次のコード

を考えてみましょう:

#ifdef __cplusplus  
    extern "C" int global; 
    extern "C" int addnumbers(int a, int b); 
#else 
     extern int global; 
#endif 

これは完全に正常に動作します。

int global; 

私の.cppファイルまたはmy .cファイルで宣言する必要があります。しかし、私が理解できないものは次のとおりです:extern "C"externの違いは何ですか?ここでは、extern "C"externの違いは何ですか?私はextern "C" int globalをコメントアウトしてみました。どうして?

私は、extern "C"がCリンケージを作るのに使われていることを知っています。だからこそ私はextern "C" int addnumbers(int,int)です。つまり、Cプログラムで使用するC++関数を記述したい場合は、extern "C"と書いています。さて、グローバル変数はどうですか?状況はここで違うと思いますか?私は、Cプログラムにglobalという名前のC++変数を使用したいが、ではないexternを使うことができる。何故ですか?これは私に直感的ではありません。

コメント:これは重複しているとは思われません。なぜなら、変数と関数を使用するときに違いがあるからです。

+1

これは重複しているとは思われません。なぜなら、変数と関数の違いをどのように使うのかということです。 – Thenewstockton

+0

私はあなたにあなたの質問にははるかに明確にするようにあなたを招待します。 –

+0

私は 'extern" Cとexternの違いを検出するのに苦労していますが、_whatは変数のextern "C"とexternの違いです。おそらく、問題は関数と変数の両方で使用すると異なるextern "C" "です。答えは単純に" no " –

答えて

-1

"C++には、Cバインディングで関数を宣言するための特別なキーワードextern" C "があります。extern" C "として宣言された関数は、関数名をシンボル名としてC関数と同じように使用します。非メンバ関数はextern "C"として宣言でき、オーバーロードすることはできません。 "

コンパイラによって生成される関数名には、C++に標準はありません。キーワードextern "C"は、C標準で関数名を生成するようにコンパイラに指示します。

-1

extern "C"は、C標準でコンパイルされたC++関数を作成するために使用され、変数とは関係がないことがわかります。CとC++の関数名の解法が異なるからです。 "void foo(int x、int y)"のように、Cコンパイラは "_foo"に変換し、C++コンパイラは "_foo_int_int"に変換します。

1

externは、次の変数(グローバル)がまだ宣言されていない可能性がありますが、別の翻訳単位でグローバルとして宣言され、リンク段階でシンボル「グローバル」がメモリ内の領域。

少数の人々がC++でネーム・マングリングの問題を解決するために使用されるCにそのシンボルがaddnumbers

ある一方で、この関数は、リンカによって addnumbers_i_i(または類似したもの)として知られるであろう、コメントとして extern "C"は、ありながら、
5

extern "C"をC++宣言(オブジェクトと関数に似ています)に付けることで、それらに "Cリンケージ"を付けることができます。これらをCコードからアクセスできるようにします。この "言語リンケージ"の指定を省略すると、コンパイラは適切なリンケージを行うために何の努力もしません。関数の場合、これはmanglingのために失敗したリンケージになります。グローバル変数の場合は、変数がマングリングを必要としないので、すべてがうまくいくかもしれません。

私のシステム(MS Visual Studio)では、C++ヘッダーファイルにextern "C"リンケージ指定を指定するのを忘れた場合、CとC++間のリンケージは機能しません。例エラーメッセージ:

error LNK2001: unresolved external symbol "int global" (?_global) 

がしばらくの間、私はdumpbinユーティリティでglobalの定義が含まれているコンパイル済みのC++ソースコードを調べたときに、私は

00B 00000014 SECT4 notype  External  | [email protected]@3HA (int global) 

を参照してくださいので、MSのVisual Studioは、グローバルの名前を狂わせます変数にはCリンケージがない限り、これはCリンケージ仕様を必須にします。


はまた、次の例を検討:グローバル変数は、名前空間内にある場合

namespace example { 
    int global; 
} 

を、Cのコードは、それへのアクセスを取得することはできません。

namespace example { 
    extern "C" int global; 
} 

結論: - それは、関数の場合、または重要ではありません

使用extern "C"あなたがCリンケージをしたい。この場合、すべてのコンパイラは、C++宣言に適切なリンケージ指定が必要になりますグローバル変数。グローバル変数の場合は、関係なく動作する可能性がありますが、保証されていない(危険な場合もあります)。