ホームページ php教程 PHP开发 C++ での extern 'C' の使用法の詳細な説明

C++ での extern 'C' の使用法の詳細な説明

Dec 19, 2016 pm 02:47 PM
extern

簡単に言うと、extern "C" は、C++ が C との互換性を保つために C 言語のシンボルを宣言または定義する方法です。言うのは簡単ですが、理解するにはまだ少し時間がかかります。まず、C++ と C の違いから始めなければなりません。

シンボル

コードから実行可能プログラムまで、コンパイルとリンクという 2 つのプロセスを経る必要があることは誰もが知っています。コンパイル フェーズでは、構文検出とコード拡張も行われます。変数をシンボルに変換すると、リンク時に実際にはシンボルを介して配置されます。コンパイラーが C および C++ コードをコンパイルする場合、変数をシンボルに変換するプロセスは異なります。この記事で使用するコンパイラは gcc4.4.7 です

まず簡単なコードを見てみましょう

/* hello.c */  
#include <stdio.h>  
  
const char* g_prefix = "hello ";  
  
void hello(const char* name)  
{  
    printf("%s%s", g_prefix, name);  
}
ログイン後にコピー

ここでのファイル名は hello.c であることに注意してください。 gcc -c hello.c を実行してコンパイルし、ターゲット ファイル hello を取得します。 o. Linux で nm を使用してターゲット ファイルのシンボル テーブルを表示すると、次の結果が得られます ($ 記号はシェル コマンド プロンプトを表します)

$ nm hello.o  
0000000000000000 D g_prefix  
0000000000000000 T hello  
                 U printf
ログイン後にコピー

これは C コードのコンパイル済みシンボル リストで、その 3 番目の列は次のとおりです。コンパイルされたシンボル名を主に調べます。自己定義のグローバル変数 g_prefix と関数 hello のコンパイルされたシンボル名は、コード内のものと同じです。 hello.c の名前を hello.cpp に変更し、gcc -c hello.cpp を再コンパイルして hello.o を取得し、nm を使用して表示します。結果は次のとおりです

0000000000000000 T _Z5helloPKc  
                 U __gxx_personality_v0  
0000000000000000 D g_prefix  
                 U printf
ログイン後にコピー

これは、C++ コードがコンパイルされた後のシンボル リストです (gcc)この時点では、g_prefix のシンボルは変更されていませんが、関数 hello のシンボルが _Z5helloPKc に変更されていることがわかります。これは、gcc が C と C++ のコードを処理していることを示しています。 C++ コードの場合は異なります。C コードの場合、変数のシンボリック名は変数そのものです (初期の頃は、コンパイラーは C コード変数の前にアンダースコア _ を追加していましたが、現在はデフォルトで追加しません。コンパイル時のコンパイル オプション -fno-leading-underscore および -fleading-underscore)、C++ コードの場合、それがデータ変数でネストされていない場合、変数名がネストされている場合はシンボル名自体になります。 (名前空間またはクラス内) または関数名である場合、シンボル名は次の規則に従います。


1 を処理するには、シンボルは _Z

2 で始まり、ネストがある場合は、その後に N が続きます。名前空間、クラス、関数の名前は長さであり、 E
3 で終わります。ネストがない場合は、直接名前の長さの後に名前が続きます
4。パラメータリスト、型とシンボルの対応関係は以下の通りです

    int    -> i  
    float  -> f  
    double -> d  
    char   -> c  
    void   -> v  
    const  -> K  
    *      -> P
ログイン後にコピー

こうすることで、コンパイル後の C++ コードで void hello (const char*) が発生する理由が簡単に理解できます シンボルは _Z5helloPKc (PKc は右から左に型に変換されます) char const * (コンパイラの内部表現)、私たちが慣れている表現は const char* (同じです)、c++filt ツールはシンボルから名前を逆にすることができます。使用方法は c です。 ++filt _Z5helloPKc

C++ が関数のオーバーロードをサポートしているのに C がサポートしていない理由も簡単に理解できます。これは、C++ では関数をシンボルに変更するときに関数のパラメーターの型を追加しますが、C では追加しないためです。関数名が同じであれば、パラメーターが異なっていれば、シンボル名は競合しません。次の例を通じて、変数名とシンボルの間のこの関係を確認できます。

/ * filename : test.cpp */  
#include <stdio.h>  
  
namespace myname  
{  
    int var = 42;  
}  
  
extern int _ZN6myname3varE;  
  
int main()  
{  
    printf("%d\n", _ZN6myname3varE);  
    return 0;  
}
ログイン後にコピー

ここでは、名前空間 namespace でグローバル変数 var を定義します。前の内容に従って、シンボル _ZN6myname3varE として変更され、外部変数 _ZN6myname3varE を手動で宣言して出力します。コンパイルして実行すると、その値はまさに var

$ gcc test.cpp -o test -lstdc++  
$ ./test  
42
ログイン後にコピー

extern "C" の値です

シンボルの概念を使えば、extern "C" の使い方が簡単に分かります

extern "C"  
{  
    int func(int);  
    int var;  
}
ログイン後にコピー

ということをコンパイラに伝えることを意味しますextern "C" の後の括弧内のコードは C コードとして扱われます。もちろん、単一のステートメント

extern "C" int func(int);  
extern "C" int var;
ログイン後にコピー

で宣言して、C 型の func と var を宣言することもできます。多くの場合、ヘッダー ファイルを作成して C 言語関数を宣言しますが、これらの関数は C および C++ コードから呼び出すことができます。C++ コードから呼び出す場合は、ヘッダー ファイルに extern "C" を追加する必要があります。そうでない場合は、C++ を使用します。 C はそのような構文をサポートしていないため、シンボルが見つかりません。また、C コードを呼び出すときに extern "C" を追加することはできません。C ライブラリ関数 memset を例に説明します。このうち、__cplusplus は C++ コンパイラで定義されたマクロです。このコードを C++ でコンパイルすると、memset は extern "C" で宣言されます。C コードでコンパイルすると、__cplusplus が定義されていないため、直接宣言されます。 . なので、構文エラーは発生しません。この手法はシステム ヘッダー ファイルでよく使用されます。


C++ での extern "C" の使用方法の詳細な説明と関連記事については、PHP 中国語 Web サイトに注目してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)