リンケージの仕様
"リンケージ指定" とは、異なる言語で記述された複数の関数 (またはプロシージャ) をリンクするためのプロトコルです。 次の呼び出し規約に影響を与えます。
名前の大文字と小文字の区別。
名前の装飾。 C では、コンパイラは名前の前にアンダースコアを付けます。 通常、これを "修飾" といいます。 C++ では、リンケージ フェーズによって型情報を保持するのに名前の装飾が使用されます (「装飾名」を参照してください)。
スタック上で想定される引数の順序。
関数の戻り値のスタックを調整する役割。 呼び出された関数または呼び出し元の関数が役割を負います。
(非表示の引数が渡されたかどうかに関係なく) 非表示の引数を渡す。
extern string-literal { declaration-list }
extern string-literal declaration
リンケージ指定により、既存コードの使用が許可され、C コードの C++ への移植が簡単になります。
Microsoft 固有の仕様 →
現在 Microsoft C++ でサポートされるリンケージ仕様は、"C" と "C++" のみです。
END Microsoft 固有の仕様
次の例では、C リンケージを持つ関数 atoi と atol を宣言します。
extern "C"
{
int atoi( char *string );
long atol( char *string );
}
これらの関数への呼び出しは C リンケージを使用して行われます。 これら 2 つの宣言で同じ結果が得られる可能性があります。
extern "C" int atoi( char *string );
extern "C" long atol( char *string );
Microsoft 固有の仕様 →
すべての Microsoft C 規格の include ファイルは、C++ コンパイルを検出する条件付きコンパイルのディレクティブを使用します。 C++ コンパイルが検出されると、プロトタイプは次のように extern "C" ディレクティブで囲まれます。
// Sample.h
#if defined(__cplusplus)
extern "C"
{
#endif
// Function declarations
#if defined(__cplusplus)
}
#endif
END Microsoft 固有の仕様
標準のインクルード ファイルの関数を extern "C" として宣言する必要はありません。
関数がオーバーロードされている場合は、同じ名前の関数のうち 1 つの関数のみリンケージ指定子を含むことができます (詳細については、「関数オーバーロード」を参照してください)。
次の表は、さまざまなリンケージ指定がどのように動作するかを示します。
リンケージ指定の影響
指定対象 |
影響 |
---|---|
オブジェクト |
そのオブジェクトのリンケージにのみ影響します。 |
関数 |
その関数と、内部で宣言されたすべての関数またはオブジェクトのリンケージに影響します。 |
クラス |
クラス内で宣言されたすべての非メンバー関数およびオブジェクトのリンケージに影響します。 |
関数に複数のリンケージ指定子がある場合、それらは一致する必要があります。関数を C と C++ 両方のリンケージを持つ関数として宣言するとエラーになります。 また、プログラム内に、リンケージ指定子を含む関数宣言と含まない関数宣言がある場合、リンケージ指定子を含む宣言を最初に記述する必要があります。 既にリンケージ指定を持つ関数の冗長な宣言には、最初の宣言で指定したリンケージが与えられます。 次に例を示します。
extern "C" int CFunc1();
...
int CFunc1(); // Redeclaration is benign; C linkage is
// retained.
int CFunc2();
...
extern "C" int CFunc2(); // Error: not the first declaration of
// CFunc2; cannot contain linkage
// specifier.
複合リンケージ指定子 ({ }) の本体内で static として明示的に宣言された関数およびオブジェクトは、静的関数またはオブジェクトとして扱われます。リンケージ指定子は無視されます。 extern キーワードを使用して宣言したかのように、他の関数やオブジェクトが動作します。 extern キーワードの詳細については、「extern を使用したリンケージの指定」を参照してください。