linux下C與C++混合編程

原文出處:http://www.cnblogs.com/dobest9014/archive/2011/04/26/2030845.html

首先,混合編程不是指在同一個文件裡寫C與C++。 比如說想在同一文件裡同時 弱類型檢查,又強類型檢查,那真夠嗆。混合編程包括:1,C引用C的頭文件;2,g生成的.o與gcc生成的.o相鏈接。

1,在用C語言寫的頭文件中,經常加上如下 保護宏定義:

/*
 *   example.h
 */
#ifndef EXAMPLE_H_
#define EXAMPLE_H_
#ifdef __cplusplus
extern "C"{
#endif
/*這裡是頭文件內容*/
/*頭文件內容結束*/
#ifdef __cplusplus
}
#endif
#endif

2,關於extern "C"

當c引用c的函數,結構體定義等時,要聲明extern "C" 從某種意義上,這倒是像是在C文件裡寫C的一種方法。事實上,由於c會將函數標示符進行修飾後使用,而C不會,所以用C編譯的fun有可能是fun_int,這樣在鏈接時會出現問題。使用extern “C”來解決這一問題,但帶來的影響是不能重載了。總之,extern "C"即叫編譯器按照C的方式去處理。

3,具體編譯命令 g++ 與 gcc

實例1:

//test.c
int fun(int a, int b)
{
  return a+b;
}
//main.cpp
#include <stdio.h>
#include "test.c"
int main()
{
  printf("%dn", fun(10, 11));
  return 0;
}

首先理解include,include會把包含的文件直接加在本文件中,和copy過來一樣。而我們直接包含了test.c文件,而不是頭文件,所以,直接:g++ -o main main.cpp 即可得到可執行文件。 實例2:

//test.c
int fun(int a, int b)
{
  return a+b;
}
//test.h
int fun(int, int);
//main.cpp
#include <stdio.h>
#include "test.h"
int main()
{
  printf("%dn", fun(10, 11));
  return 0;
}

正確的編譯方法:

g++ -c test.c                //生成test.o
g++ -c main.cpp              //生成main.cpp
g++ -o main test.o main.o    //鏈接,生成main可執行文件

錯誤的編譯方法:

gcc -c test.c                //生成test.o
g++ -c main.cpp              //生成main.cpp
g++ -o main test.o main.o    //鏈接,生成main可執行文件

如果,想使第二種方法正確,則在test.h中使用extern “C”聲明,或者在main.cpp中,使用extern "C"聲明 實例3 正確寫法1

//test.c
int fun(int a, int b)
{
    return a+b;
}
//test.h
#ifdef __cplusplus
extern "C"{
#endif
int fun(int, int);
#ifdef __cplusplus
}
#endif
//main.cpp
#include <stdio.h>
#include "test.h"
int main()
{
    printf("%dn", fun(10, 11));
    return 0;
}

正確寫法2

//test.c
int fun(int a, int b)
{
    return a+b;
}
//test.h
int fun(int, int);
//main.cpp
#include <stdio.h>
extern "C"
{
#include "test.h"
}
int main()
{
    printf("%dn", fun(10, 11));
    return 0;
}

正確寫法3

//test.c
int fun(int a, int b)
{
    return a+b;
}
//test.h
int fun(int, int);
//main.cpp
#include <stdio.h>
extern "C" int fun(int, int);
int main()
{
    printf("%dn", fun(10, 11));
    return 0;
}

其中正確寫法 3 很有意思,在main.cpp中,並沒有包含test.h, 這裡寫的extern "C" int fun(int, int),其實就是頭文件內容。把頭文件內容人工手寫在main.cpp中和用include包含進來,是一樣效果,這樣就好理解了。 include“test.h” ,其實也就是寫了一句 extern "C" int fun(int, int)。所以嚴格來說,.h文件無所謂是屬於C還是C++,被誰包含,就屬於那種語言。

###4, 關於g++,gcc 直接引用http://blog.ednchina.com/olivernie/161559/message.aspx上的原文,這段話是轉載,不是我寫的。 在國內搜索引擎搜索gcc與g++,大多都是在說g++會調用gcc來編譯c++文件,國外stackoverflow大多再說gcc調用g++。有爭議,先mark

gcc和g++都是GNU(組織)的一個編譯器。

誤區一: gcc只能編譯c代碼,g只能編譯c代碼 兩者都可以,但是請注意: 1.後綴為.c的,gcc把它當作是C程序,而g當作是c程序;後綴為.cpp的,兩者都會認為是c程序,注意,雖然c是c的超集,但是兩者對語法的要求是有區別的。C的語法規則更加嚴謹一些。 2.編譯階段,g會調用gcc,對於c代碼,兩者是等價的,但是因為gcc命令不能自動和C++程序使用的庫聯接,所以通常用g來完成鏈接,為了統一起見,乾脆編譯/鏈接統統用g了,這就給人一種錯覺,好像cpp程序只能用g似的。

誤區二: gcc不會定義__cplusplus宏,而g會 實際上,這個宏只是標誌著編譯器將會把代碼按C還是C語法來解釋,如上所述,如果後綴為.c,並且採用gcc編譯器,則該宏就是未定義的,否則,就是已定義。

誤區三: 編譯只能用gcc,鏈接只能用g++ 嚴格來說,這句話不算錯誤,但是它混淆了概念,應該這樣說:編譯可以用gcc/g++,而鏈接可以用g或者gcc -lstdc。因為gcc命令不能自動和C++程序使用的庫聯接,所以通常使用g來完成聯接。但在編譯階段,g會自動調用gcc,二者等價。

用gcc編譯c++文件:

#gcc -o test.exe test.cpp -lstdc++

书籍推荐