CとC++インターフェース関数の相互呼び出しの実現


一、CまたはC++コンパイルの四つのステップ
(一)前処理
この手順では、コンパイラは、ソースプログラムの「萍」で始まる文を処理します。この中で、〹includeの原理は、ターゲットファイルの内容を本ファイルに導入することです。
(二)コンパイル
このステップでは、コンパイラは、第1のステップで生成した各ファイルをそれぞれアセンブル言語ファイルに変換する。このプロセスでは、すべての関数の名前は、アセンブリファイルの一意の識別として記号に変換されます。C言語関数は、一般的に直接関数名をその固有の識別記号として使用しますが、C++関数は、多くの場合、関数名に様々な接頭辞または接頭辞を加えて、その識別として機能void Print(int num)を使用する必要があります。コンパイラがC言語としてコンパイルしている場合、この関数は、アセンブルファイルの符号をPrintとし、C+++と見なすと、そのシンボルはPrint_とすることができる。int(gccまたはg++における関数名の変更は名前空間なども考慮される)これもC+++サポート関数の重負荷の原因である。
(三)アセンブリ
このステップでは、コンパイラは、第2のステップで生成した各ファイルをそれぞれバイナリファイルに変換しますが、まだ実行可能なファイルではありません。
(四)リンク
このステップでは、コンパイラは、3番目のステップで生成された各ファイルのために、例えば、main関数でPrint()関数を呼び出しても、Print()関数がどこにあるかは分かりませんが、Print()関数の本体があるそのファイルには、Print()関数のアドレスが表記されています。したがって、コンパイラは、メイン関数でPrint()関数を呼び出すところにPrint()関数のアドレスを表示し、プログラム実行中のアドレスジャンプにターゲットアドレスを提供しますが、コンパイラはこのステップを行うことができる前提となります。main()関数でPrint()関数の識別、Print()関数本体があるファイルにPrint()関数の表示は同じです。違ったら、リンクエラーが発生します。
二、CとC++インターフェースが相互に起動するキー
上記から分かるように、一つの関数を呼び出すには、呼び出しの記号と関数本体の記号が同じであることが重要条件であり、CとC+はコンパイルの過程で関数名を記号を識別する方法とは異なるので、相互呼出の鍵は、統一インターフェース関数の識別記号であり、一般的に採用される方法は、C関数を用いて改編した方法は,インターフェース関数の改編方式を統一する。
三、extern「C」
extern「C」の役割は、コンパイラがC関数名で改編する方法を説明し、修飾された関数を識別記号に改編することです。extern「C」は普通C++ファイルに使われます。

extern "C" void Print(int num);
extern "C" {
 void Input(int* num);
 void Output(int num);
};
以上がextern「C」の2つの書き方です。このように、上記の3つの関数はいずれもCの方式で符号化され、gccまたはg+コンパイルでPrint、Input、Outputに変更されます。
四、C関数コールC++インターフェース
(一)非メンバ関数の呼び出し
関数を呼び出した宣言と定義は以下の通りです。

/**
 * called.h
 */
#ifndef CALLED_H
#define CALLED_H

extern "C" void PrintCpp(void);

#endif


/**
 * called.cpp
 */
#include <iostream>
#include "called.h"

using namespace std;

void
PrintCpp(void) {
 cout << "I\'m cpp." << endl;
}

最終コールは以下の通りです。

/**
 * call.c
 */
#include "called.h"

int
main(int argc, char const* argv[]) {
 PrintCpp();
 return 0;
}

(二)クラスメンバー関数を呼び出す(インターフェース関数にはクラスポインタがない)
関数宣言と定義は以下の通りです。

/**
 * called.h
 */
#ifndef CALLED_H
#define CALLED_H

class Console {
public:
 Console();
 virtual void PrintDouble(double num);
};

extern "C" void CppPrintDouble(double num);

#endif

/**
 * called.cpp
 */
#include <iostream>
#include "called.h"

using namespace std;

Console::Console() {}

void
Console::PrintDouble(double num) {
 cout << num << endl;
}

Console* console = new Console();

void
CppPrintDouble(double num) {
 console->PrintDouble(num);
}
最終コールは以下の通りです。

/**
 * call.c
 */
#include "called.h"

int
main(int argc, char const* argv[]) {
 CppPrintDouble(3.14);
 return 0;
}
五、C++関数コールCインターフェース
関数を呼び出した宣言と定義は以下の通りです。

/**
 * called.h
 */
#ifndef CALLED_H
#define CALLED_H

void PrintC(void);

#endif

/**
 * called.c
 */
#include <stdio.h>

#ifdef __cplusplus
extern "C" {
#endif
#include "called.h"
#ifdef __cplusplus
};
#endif

void
PrintC(void) {
 printf("I\'m C.
"); }
最終コールは以下の通りです。

/**
 * call.cpp
 */
#ifdef __cplusplus
extern "C" {
#endif
#include "called.h"
#ifdef __cplusplus
};
#endif

int
main(int argc, char const* argv[]) {
 PrintC();
 return 0;
}
caled.cファイルの中で、菗ifdef_ucplusplus/*/*/钾endifとexternの「C」の役割はg+コンパイラの「.c」ファイルをC++でコンパイルし、gccでコンパイルすれば、直接に「caled.h」と書けばいいです。
ここでCとC++インタフェース関数の相互呼出についての実現された文章を紹介します。より多くの関連CとC+インタフェース関数の呼び出し内容は以前の文章を検索してください。または下記の関連記事を引き続きご覧ください。これからもよろしくお願いします。