CとC++の混合プログラミングの問題

3994 ワード

次のコードを分析します.

/*=======sum.h=========*/

#ifndef SUM_H
#define SUM_H
#include 

int sum(int a,int b);


#endif;

/*=======sum.c=========*/

#include "sum.h"


int sum(int a,int b)
{
int c=a+b;
return c;
}

/*====main.cpp======*/

#include "sum.h"

void mian(){

cout << sum(1,2)< 
 

以上の3つのファイルを呼び出し、コンパイルはパスしましたが、実行には次の問題が発生します.
obj:error LNK 2001:解析できない外部符号「int__cdeclsum(int,int)」(?sum@@YAHHH@Z) E:\Programming\Grapic\test\Debug\test.Exce:fatal error LNK 1120:1個の解析不能外部コマンド
問題はどこですか.メールでcppでsumが呼び出されました.c,つまりC++プログラムでCプログラムが呼び出された場合,対応する処理を行わないとリンクエラーが発生する.
extern"C"はコンパイルによって生成された内部シンボル名がC規則を用いることを示す.C++は関数のリロードをサポートしますが、Cはサポートしていません.両者のコンパイルルールも異なります.関数がC++によってコンパイルされたシンボルライブラリの名前はC言語とは異なる.例えば、ある関数のプロトタイプをvoid foo(int x,int y);この関数は、Cコンパイラによってコンパイルされたシンボルライブラリの名前が_foo、C++コンパイラは像_を生成しますfoo_int_intなどの名前(コンパイラによって生成される可能性のある名前は異なるが、同じメカニズムを採用しており、生成される新しい名前を「mangled name」と呼ぶ).foo_int_intという名前には,関数名,関数パラメータ数,タイプ情報が含まれており,C++はこのようなメカニズムによって関数リロードを実現している.
では、CでC++コードを呼び出すと、どのようにC++でCのコードを呼び出すのでしょうか.
extern"C"はコンパイルによって生成された内部シンボル名がC規則を用いることを示す.
1.C++でCを呼び出すにはどうすればいいですか?
C++呼び出しC、extern"C"の役割は、C++コネクタに呼び出し関数の記号を探すときにCの方式を採用させることです.
本文の冒頭に提出した筆記試験問題はこのように修正することができる.

/*=======sum.h=========*/

#ifndef SUM_H
#define SUM_H
#include 

int sum(int a,int b);


#endif;

/*=======sum.c=========*/

#include "sum.h"


int sum(int a,int b)
{
int c=a+b;
return c;
}

/*====main.cpp======*/

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

void mian(){

cout << sum(1,2)< 
 

実行成功
ここまで悪くないと信じて
2.CでC++を呼び出すにはどうすればいいですか?
CでC++関数を参照する(CはC++を呼び出し、extern"C"を使用すると、コンパイラにcppファイルのextern"C"で定義された関数をCの方法でカプセル化インタフェースをコンパイルするように伝える.もちろん、インタフェース関数のC++構文はC++でコンパイルする)
実行:test 1.obj:error LNK 209:解析できない外部シンボル_sum、この記号は関数_mainではE:ProgrammingGrapictestDebugtest.Exce:fatal error LNK 1120:1個の解析不能外部コマンド

/*=======sum.h=========*/

#ifndef SUM_H
#define SUM_H
#include 

int sum(int a,int b);


#endif;

/*=======sum.cpp=========*/

#include "sum.h"


extern "C"
{
int sum(int a,int b)
{
int c=a+b;
return c;
}
}

/*====main.c======*/

#include "sum.h"

void mian(){

cout << sum(1,2)< 
 

3.標準仕様書の書き方
一般的には、関数宣言をヘッダファイルに配置します.私たちの関数がCまたはC++で使用される可能性がある場合、誰が呼び出されたのか判断できません.extern「C」に関数を宣言するかどうかは判断できません.したがって、追加できます.

#ifdef __cplusplus

extern "C"

{

#endif

//    

#ifdef __cplusplus

}

#endif

以上の声明形式を利用すれば総合的に運用できる.CでC++言語の関数と変数を参照する場合、C++の関数または変数はextern"C"{}に宣言されますが、C言語ではextern"C"は使用できません.そうしないとコンパイルエラーになります.(エラーが発生しました:error C 2059:syntax error:'string'です.このエラーはネット上で長い間探していましたが、国内のウェブサイトでは直接原因を説明していません.理由はextern「C」がC++のキーワードで、Cではありません.すべてエラーが発生します.

/*=======sum.h=========*/

#ifndef SUM_H
#define SUM_H
#include 

int sum(int a,int b);


#endif;

/*=======sum.cpp=========*/

#include "sum.h"


int sum(int a,int b)
{
int c=a+b;
return c;
}

/*====main.c======*/

#include "sum.h"

void mian(){

cout << sum(1,2)<