ProgrammingC++開発者

C++での外部関数(extern 'C')メカニズムはどのように実装され、何のために必要ですか?

Hintsage AIアシスタントで面接を突破

回答。

extern "C"メカニズムはC言語のコードとの相互作用を提供します。これにより、Cライブラリを使用でき、C++と他の言語との接続が容易になります。

問題の歴史: C++はCをベースに構築されましたが、関数のオーバーロードやその他の機能をサポートするための「名前のマングリング」を含む独自の特徴がありました。

問題: C++では関数名が追加の構造(マングル)を持つシンボルにコンパイルされますが、Cではそのような変換はありません。その結果、追加の努力なしにCコードのヘッダーをC++コンパイラーに単純に接続することはできません。

解決策: extern "C"構文内で関数をラップすることで「名前のマングリング」を無効にし、Cコンパイラーでコンパイルされたコードに対してそれらを可視化します。

コード例:

#ifdef __cplusplus extern "C" { #endif void foo(int); #ifdef __cplusplus } #endif

主な特徴:

  • Cとの互換性のための名前のマングリングの無効化
  • サードパーティライブラリとの統合に使用
  • 「extern "C"」の範囲内での関数のオーバーロードは許可されていません

トリッキーな質問。

extern "C"で関数をオーバーロードできますか?

いいえ、標準のC関数名が使用されるため、オーバーロードは不可能です。

テンプレート関数をextern "C"として宣言したらどうなりますか?

コンパイルエラーが発生します。なぜなら、テンプレートはC++の別の機能であり、Cではサポートされていないからです。

クラスレベルでextern "C"を使用できますか?

いいえ、関数や変数のためだけに、クラスやメソッドには使用できません。

一般的なエラーとアンチパターン

  • 異なるファイルのリンクに関する混乱
  • extern "C"での関数のオーバーロードの試み
  • Cではサポートされていないすべてをextern "C"内で使用しようとすること:クラス、テンプレート、オーバーロード

実際の例

ネガティブケース

C++プロジェクトがextern "C"なしでサードパーティのCライブラリを接続し、コードがシンボル名の不一致のためにリンクされない。

利点:

  • サードパーティライブラリと連携できる(すべてを正しく行った場合)

欠点:

  • 名前のマングリングを忘れるとエラーが発生し、リンクが作成されません。

ポジティブケース

サードパーティのCライブラリを統合する際に、ヘッダーファイルでextern "C"が使用される。

利点:

  • 確実なリンキング
  • 互換性の簡略化

欠点:

  • 関数のオーバーロードがありません。