サーチ…
前書き
リンケージ仕様は、Cなどの別の言語で書かれた宣言と一緒に宣言をリンクできるように宣言をコンパイルするようにコンパイラに指示します。
構文
- extern 文字列リテラル { 宣言-seq ( opt )}
- extern 文字列リテラル 宣言
備考
この標準では、C ++がCと互換性を持つようにするためには、すべてのコンパイラがextern "C"
をサポートする必要があり、 extern "C++"
は、囲みリンケージ仕様をオーバーライドしてデフォルトを復元するために使用されます。サポートされている他のリンケージ仕様は実装定義です。
Unixライクなオペレーティングシステム用シグナルハンドラ
シグナルハンドラはC呼び出し規約を使用してカーネルによって呼び出されるので、関数をコンパイルするときにC呼び出し規約を使用するようにコンパイラに指示する必要があります。
volatile sig_atomic_t death_signal = 0;
extern "C" void cleanup(int signum) {
death_signal = signum;
}
int main() {
bind(...);
listen(...);
signal(SIGTERM, cleanup);
while (int fd = accept(...)) {
if (fd == -1 && errno == EINTR && death_signal) {
printf("Caught signal %d; shutting down\n", death_signal);
break;
}
// ...
}
}
CライブラリヘッダーをC ++と互換性にする
ほとんどの宣言はCとC ++の両方で有効なので、ACライブラリヘッダーは通常C ++プログラムに組み込むことができます。たとえば、次のfoo.h
考えてfoo.h
。
typedef struct Foo {
int bar;
} Foo;
Foo make_foo(int);
make_foo
の定義は個別にコンパイルされ、ヘッダとともにオブジェクト形式で配布されます。
C ++プログラムは#include <foo.h>
することができますが、コンパイラーはmake_foo
関数がCシンボルとして定義されていることをmake_foo
せず、おそらく名前が変更された名前で検索しようとします。それがの定義を見つけることができたとしてもmake_foo
ライブラリ内ではなく、すべてのプラットフォームは、呼び出し時に呼び出し規約C ++を使用するCおよびC ++、およびC ++コンパイラの同じ呼び出し規約を使用しmake_foo
場合セグメンテーションフォールトが発生する可能性がある、 make_foo
Cの呼び出し規約で呼び出されることを期待しています。
この問題を解決する方法は、ヘッダーのほとんどすべての宣言をextern "C"
ブロックでextern "C"
です。
#ifdef __cplusplus
extern "C" {
#endif
typedef struct Foo {
int bar;
} Foo;
Foo make_foo(int);
#ifdef __cplusplus
} /* end of "extern C" block */
#endif
今ときfoo.h
Cプログラムから含まれている、それだけで普通の宣言として表示されますが、ときfoo.h
C ++のプログラムから含まれている、 make_foo
内側になるextern "C"
ブロックとコンパイラを探すために知っているだろうunmangledな名前とCの呼び出し規約を使用します。