C++ での extern C の使用

Mehvish Ashiq 2023年10月12日
C++ での extern C の使用

このチュートリアルでは、C++ での extern "C" の影響を理解するための前提条件である、C++ での名前マングリングについて説明します。 さらに、C++ プログラミングにおける extern "C" について教育します。

C++ での extern "C" の使用

extern キーワードを使用して、外部変数とも呼ばれ、メソッド (関数) の外部で定義されるグローバル変数を定義します。 プログラム全体でこれらの変数を使用し、関数を使用して値を変更できます。

extern キーワードが C++ ファイルで使用されている場合、C++ の特定の関数名には C リンケージがあります。 この場合、コンパイラは関数名をマングルしません。

C++ プログラミングでマングリングという名前は何ですか?

これは、C++ の extern キーワードを理解するための前提条件です。 では、まず名前のマングリングについて学びましょう。

C++ プログラミングは、関数のオーバーロード 機能をサポートしています。 同じ名前の複数の関数を使用できますが、引数の数とデータ型が異なります。

ここでは、return データ型は考慮されていません。 問題は、オーバーロードされた関数がオブジェクト コードでどのように区別されるかです。

関数名は、それぞれの引数に関する詳細を追加することにより、オブジェクト コードで変更されます。 ここで引数の情報を追加するために使用される手法は、Name Mangling です。

C++ プログラミングには、名前マングリングの標準化された手法がないことに注意してください。 これが、さまざまなコンパイラがさまざまな手法を使用する理由です。

以下は、C++ プログラミングでの名前マングリングの実際のデモンストレーションです。 以下のコードには、calculate という名前の 3つのオーバーロードされた関数と 1つの main メソッドがあります。

コード例:

int calculate(int number) { return number * number; }
double calculate(double number) { return number * number; }
float calculate(float number) { return number * number; }
int main(void) {
  int number1 = calculate(3);
  double number2 = calculate(3.38);
  float number3 = calculate(3.00);
}

C++ コンパイラは、オーバーロードされた関数を区別するために上記のコードを変更します。

コード例:

int __calculate_i(int number) { return number * number; }
double __calculate_d(double number) { return number * number; }
float __calculate_f(float number) { return number * number; }

int __main_v(void) {
  int number1 = __calculate_i(3);
  double number2 = __calculate_d(3.38);
  float number3 = __calculate_f(3.00);
}

C プログラミングは、関数のオーバーロードをサポートしていません。 そのため、C コードを C++ ファイルにリンクするときに、関数名が変更されないようにする必要があります。

以下のコード スニペットは、コンパイラが printf() 関数の名前を変更し、変更/更新された printf() 関数の定義を見つけることができないため、エラーを生成します。

コード例:

int printf(const char *format, ...);
int main() { printf("I'm learning the use of Extern in C++"); }

この問題を解消するために、C++ プログラミングで extern キーワードを使用します。 C++ コンパイラは、extern "C" {} ブロック内のコードを見つけるたびに、関数の名前がマングルされていないことを確認します。

これは、関数の名前が変更されないことを意味し、プログラムを正常に実行できるようにします。 異なるコンパイラは、これらのコード ブロックに対して異なる出力を生成する可能性があることに注意してください。

コード例:

extern "C" {
int printf(const char *format, ...);
}
int main() { printf("I'm learning the use of Extern in C++"); }

出力:

I'm learning the use of Extern in C++

したがって、extern "C" は、namespace の範囲内になければならないリンケージ仕様です。 extern "C" はクラス メンバーを無視します。

C++ ファイルで C コードをリンクする場合は常に、このキーワードを使用する必要があります。

著者: Mehvish Ashiq
Mehvish Ashiq avatar Mehvish Ashiq avatar

Mehvish Ashiq is a former Java Programmer and a Data Science enthusiast who leverages her expertise to help others to learn and grow by creating interesting, useful, and reader-friendly content in Computer Programming, Data Science, and Technology.

LinkedIn GitHub Facebook