C和C 混合程式設計之 extern 「C」的使用

2021-08-07 19:03:59 字數 2041 閱讀 9802

c++號稱是c語言的超集,也確實,從語言的基本語法上,c++是包含所有c語言的語法的,而且c++為了相容c,連c語言的標準庫也被納入到c++的標準庫中,比如在c++中我們仍然可以使用,它就是c++標準庫的一部分(注意最好用新的標準,而不是老的)。

但是,c++和c語言的編譯器在有些地方還是有差別的。比如,c++是支援物件導向的特性(儘管c++被稱為不徹底的物件導向語言),物件導向就要支援函式過載,而函式過載的實現和c++編譯器是分不開的。

比如有:

int max(int a, int b);

double max(double a,double b);
這兩個函式。

這兩個函式同時存在,在c語言中是不可以的,因為c語言不支援過載,但是在c++中完全沒有問題,因為c++是支援過載的。

那麼為什麼會這樣呢?

這要從編譯器的角度來看:

c編譯器將int max(int a,int b)函式編譯後,在符號庫中的名字為_max(不同編譯器可能有不同的形式)

c編譯器將double max(double a,double b)函式編譯後,在符號庫中的名字也為_max。所以在c語言中,這兩個函式是不能共存的的,編譯時會提示錯誤。

但是c++編譯器則不同

c++編譯器將int max(int a, int b)編譯後,在符號表中的名字為:

_max_int_int

而另乙個則為_max_double_double。這兩者並不衝突。

這也是c++支援函式過載的根本原因。不過,這也從另一面說明了:函式過載其實不是多型,頂多算是編譯時多型。

在c++和c語言混合程式設計時,前面已經說過,c++的語法是完全包含c語言的語法的,所以不用擔心語法上出現什麼問題。出現問題的主要原因在編譯和鏈結時。

思考這樣一件事情:

我們在linux下程式設計的時候,經常會用到核心的庫,我們知道linux核心使用c語言寫的。如果這些庫採用了c語言的編譯器進行編譯,而我們的程式是用c++開發的,要用c++進行編譯,那麼會出現什麼問題?

比如:我們有個.c檔案p.c,內容如下:

#include void print(int a,int

b)

我們用gcc –c命令編譯它,生成p.o檔案

然後我們又p.h檔案,裡面是print函式的原型宣告,如下:

void print(int a,int b);
我們又有main.cpp檔案,內容如下

#include using

namespace

std;

#include

"p.h

"int

main()

這次我們用g++ -c進行編譯,生成main.o檔案

然後我們用g++鏈結兩個.o檔案,這時我們會發現,報錯:

這時為什麼呢?

因為:p.c我們使用的是c語言的編譯器gcc進行編譯的,其中的函式print編譯之後,在符號表中的名字為 _print

而我們鏈結的時候採用的是g++進行鏈結,也就是c++鏈結方式,程式在執行到呼叫print函式的**時,會在符號表中尋找_print_int_int(是按照c++的鏈結方法來尋找的,所以是找_print_int_int而不是找_print)的名字,發現找不到,所以會t提示「未定義的引用」

此時如果我們在對print的宣告中加入 extern 「c」 ,這個時候,g++編譯器就會按照c語言的鏈結方式進行尋找,也就是在符號表中尋找_print,這個時候是可以找到的,是不會報錯的。比如我們修改p.h為:

extern"c

"void print(int a,int b);

這是結果為:

所以extern 「c」 用到函式宣告之前,它的作用就是告訴編譯器,對於該函式的鏈結要採用c語言編譯器的鏈結方式,也就是告訴編譯器找_fun,而不是_fun_int_int。

如果有多個函式宣告都需要在前面加extern 「c」,那可以用extern 「c」{}的形式。

C C 混合程式設計 extern C

1.引言 c 語言的建立初衷是 a better c 但是這並不意味著c 中類似c語言的全域性變數和函式所採用的編譯和連線方式與c語言完全相同。作為一種欲與c相容的語言,c 保留了一部分過程 式語言的特點 被世人稱為 不徹底地物件導向 因而它可以定義不屬於任何類的全域性變數和函式。但是,c 畢竟是一...

c和c 混合編譯的問題(extern C )

1.引言 c 語言的建立初衷是 a better c 但是這並不意味著c 中類似c語言的全域性變數和函式所採用的編譯和連線方式與c語言完全相同。作為一種欲與c相容的語言,c 保留了一部分過程式語言的特點 被世人稱為 不徹底地物件導向 因而它可以定義不屬於任何類的全域性變數和函式。但是,c 畢竟是一種...

C 和C 混合程式設計

由於歷史原因,很多時候我們的 並不完全是使用.net寫成的。這時候和以往c 的混合程式設計就顯得相當重要了。最近碰到了這樣的問題,將方法簡要記述如下。要在c 中呼叫c 函式,大體的思路是這樣的 首先將c 函式寫成dll形式的庫,然後在c 中匯入dll中的函式進行呼叫。具體的 類似這樣 c 1int ...