標籤:使用 ar strong 檔案 sp 問題 代碼 on c
extern 變數/函數
這種情況下的extern說明變數或者函式宣告在其他的源檔案裡,而不用include標頭檔的方式來引用該函數,在連結時,連結器在各個模組中搜尋這個變數或者函數來進行最終連結。
extern 變數
在一個源檔案裡定義了一個數組:char a[6];
在另外一個檔案裡用下列語句進行了聲明:extern char *a;
請問,這樣可以嗎?
答案與分析:
不可以,程式運行時會告訴你非法訪問。原因在於,指向類型T的指標並不等價於類型T的數組。extern char *a聲明的是一個指標變數而不是字元數組,因此與實際的定義不同,從而造成運行時非法訪問。應該將聲明改為extern char a[ ]。
extern 函數
當函數提供方單方面修改函數原型時,如果使用方不知情繼續沿用原來的extern申明,這樣編譯時間編譯器不會報錯。但是在運行過程中,因為少了或者多了輸入參數,往往會照成系統錯誤,這種情況應該如何解決?
答案與分析:
目前業界針對這種情況的處理沒有一個很完美的方案,通常的做法是提供方在自己的xxx_pub.h中提供對外部介面的聲明,然後調用方include該標頭檔,從而省去extern這一步。以避免這種錯誤。
extern “C”
在C++環境下使用C函數的時候,常常會出現編譯器無法找到obj模組中的C函數定義,從而導致連結失敗的情況,應該如何解決這種情況呢?
答案與分析:
C++語言在編譯的時候為瞭解決函數的多態問題,會將函數名和參數聯合起來產生一個中間的函數名稱,而C語言則不會,因此會造成連結時找不到對應函數的情況,此時C函數就需要用extern “C”進行連結指定,這告訴編譯器,這是一個用C寫成的函數,請用C的方式來連結它們,不要產生用於連結的中間函數名。
帶extern “C”的代碼在處理函數名稱時,直接使用函數的名稱,不採用特別的方法產生一個中間函數名稱;
而沒有帶extern ”C”的代碼在處理函數名稱時,使用特別方法產生一個中間函數名稱。所以C++函數在使用C函數時,加上extern “C”才能正確的找到指定的函數。
解決方案
1.如果函數庫沒有考慮C++引用的情況,已產生庫檔案。我們在使用它的標頭檔時,可以如此使用可解決串連問題,這樣時候後編譯在引用cgi.h中的函數時,會按照C語言方式引用:
extern "C"{
#include "cgi.h"
}
2.如果要寫一個C函數庫,我們應當盡量採用如下書寫方式,而避免C++使用者出現1中的問題。
//在cgi.h檔案開始處
#ifdef __cplusplus
extern "C"{
#endif /* __cplusplus */
…
…
//cgi.h檔案結束的地方
#ifdef __cplusplus
}
#endif /* __cplusplus */
extern關鍵字總結