24

重複の可能性:
C++ で extern “C”{ #include <foo.h> } が必要なのはなぜですか?

次のようにコーディングされたプログラムをよく見てきました。

extern "C" bool doSomeWork() {
  //
  return true;
}

extern "C"ブロックを使用する理由 これを C++ の何かに置き換えることはできますか? を使用する利点はありますextern "C"か?

これを説明するリンクが表示されますが、既に C++ があるのに、なぜ C で何かをコンパイルする必要があるのでしょうか?

4

2 に答える 2

37

extern "C" は、名前が壊れないようにします。

次の場合に使用されます。

  1. C++でCライブラリを使用する必要があります

    extern "C" int foo(int);
    
  2. 一部の C++ コードを C にエクスポートする必要があります

    extern "C" int foo(int) { something; }
    
  3. 共有ライブラリのシンボルを解決する機能が必要です -- したがって、マングリングを取り除く必要があります

    extern "C" int foo(int) { something; }
    ///
    typedef int (*foo_type)(int);
    foo_type f = (foo_type)dlsym(handle,"foo")
    
于 2009-08-18T06:35:30.867 に答える
17

extern "C" が意味を持つ場所の 1 つは、C コードとしてコンパイルされたライブラリにリンクする場合です。

extern "C" {
  #include "c_only_header.h"
}

そうしないと、ライブラリには C リンケージ (_myfunc) を使用する関数が含まれているため、リンカ エラーが発生する可能性がありますが、ライブラリのヘッダーを C++ コードとして処理する C++ コンパイラは、関数の C++ シンボル名 ("_myfunc@XAZZYE" - これはマングリングと呼ばれ、コンパイラごとに異なります)。

extern "C" が使用されるもう 1 つの場所は、C++ で記述された関数に対しても C リンケージを保証することです。

extern "C" void __stdcall PrintHello() {
  cout << "Hello World" << endl;
}

このような関数は DLL にエクスポートでき、コンパイルによってその名前が変更されないため、他のプログラミング言語から呼び出すことができます。同じ関数の別のオーバーロードを追加した場合。

extern "C" void __stdcall PrintHello() {
  cout << "Hello World" << endl;
}
extern "C" void __stdcall PrintHello(const char *name) {
  cout << "Hello, " << name << endl;
}

ほとんどのコンパイラはこれをキャッチするため、DLL パブリック関数で関数オーバーロードを使用できなくなります。

于 2009-08-18T06:42:20.043 に答える