サーチ…


前書き

リンケージ仕様は、Cなどの別の言語で書かれた宣言と一緒に宣言をリンクできるように宣言をコンパイルするようにコンパイラに指示します。

構文

  • extern 文字列リテラル { 宣言-seqopt )}
  • 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の呼び出し規約を使用します。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow