程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> extern "C"的簡單解析

extern "C"的簡單解析

編輯:關於C語言

extern "C"包含雙重含義,從字面上即可得到:首先,被它修飾的目標是 "extern”的;其次,被它修飾的目標是 "C”的。
首先來看一下
a.在一個文件內,如果外部變量不在文件的開頭定義,其有效范圍只限定在定義到文件的結束處。如果在定義前需要引用該變量,則要在引用之前用關鍵字 "extern” 對該變量做“外部變量”,表示該變量是一個已經定義的外部變量。有個這個聲明,就可以從聲明處起合理地使用該變量了。"extern”起到了擴展作用域的作用。

#include <stdio.h>
 A;
    printf( A=;

b.在多文件的程序中,如果多個文件都要使用同一個外部變量,不能在各個文件中各定義一個外部變量,否則會出現“重復定義”的錯誤。正確的做法是:在任一個文件中定義外部變量,其他文件用 "extern”對變量做“外部變量聲明”。在編譯和連接時,系統會由此知道該變量是一個已經在別處定義的外部變量,這樣在本文件就可以合法地使用該外部變量了。

#include <stdio.h>
 A = ;

 A;
 A*

。extern說明變量或者函數定義在其他的源文件裡,而不用include頭文件的方式來引用該函數,在鏈接時,鏈接器在各個模塊中搜索這個變量或者函數來進行最終鏈接。
c.外部函數
在定義函數時,如果在最左端加關鍵字extern,表示此函數是外部函數。C語言規定,如果在定義時省略extern,則隱含為外部函數。而內部函數必須前加static關鍵字;
在需要調用此函數的文件中,用extern對函數作聲明,表示該函數是在其他文件中定義的外部函數。
"C”的含義:(extern “C”)
C++通過函數參數的不同類型支持重載機制,編譯器根據參數為每個重載函數產生不同的內部標識符。例如編譯器為void Eat(Beef …);void Eat(Fish …);void Eat(Chicken …);三個Eat 函數產生象_eat_beef、_eat_fish、_eat_chicken 之類的內部標識符(不同的編譯器可能產生不同風格的內部標識符)。
如果 C++程序要調用已經被編譯後的C 函數,該怎麼辦?
假設某個 C 函數的聲明如下:

 foo( x,  y);

該函數被C 編譯器編譯後在庫中的名字為_foo,而C++編譯器則會產生像_foo_int_int之類的名字用來支持函數重載和類型安全連接。由於編譯後的名字不同,C++程序不能直接調用C 函數。C++提供了一個C連接交換指定符號extern“C”來解決這個問題。
例如:

 foo( x, 

}

這就告訴C++編譯譯器,函數foo 是個C 連接,應該到庫中找名字_foo 而不是找_foo_int_int。C++編譯器開發商已經對C 標准庫的頭文件作了extern“C”處理,所以我們可以用#include 直接引用這些頭文件。

假設有C文件:

 _C_H_

  add( x, 
 add( x,  x+

在C++下調用add()函數

#include <iostream>
 , 

產生錯誤:無法解析的外部符號 "int __cdecl add(int,int)" (?add@@YAHHH@Z),該符號在函數 _main 中被引用
為了解決這個問題,我們需要使用extern "C"。改寫C文件

 _C_H_ 

  add( x, 

文件為*.c,__cplusplus沒有被定義,extern "C" {}這時沒有生效,對於C語言只是extern int add(int, int);而編譯c++源文件,__cplusplus被定義,對於C++他看到的是extern "C" {extern int add(int, int);},編譯器就會知道add(1, 0)調用的是C連接。
:很多DLL的生成文件(XXX.c)中常出現extern "C" ,windows采用C語言編譯創建dll,C程序可以正確調用DLL,而當用戶使用C++調用DLL時,extern "C" {}就起作用了。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved