extern c

鏈接指示符extern C
如果程序員希望調用其他程序設計語言尤其是C 寫的函數那麼調用函數時必須
告訴編譯器使用不同的要求例如當這樣的函數被調用時函數名或參數排列的順序可能
不同無論是C++函數調用它還是用其他語言寫的函數調用它
程序員用鏈接指示符linkage directive 告訴編譯器該函數是用其他的程序設計語言
編寫的鏈接指示符有兩種形式既可以是單一語句single statement 形式也可以是復
合語句compound statement 形式
// 單一語句形式的鏈接指示符
extern "C" void exit(int);
// 複合語句形式的鏈接指示符
extern "C" {
int printf( const char* ... );
int scanf( const char* ... );
}
// 複合語句形式的鏈接指示符
extern "C" {
#include <cmath>
}
鏈接指示符的第一種形式由關鍵字extern 後跟一個字符串常量以及一個普通的函數
聲明構成雖然函數是用另外一種語言編寫的但調用它仍然需要類型檢查例如編譯器
會檢查傳遞給函數exit()的實參的類型是否是int 或者能夠隱式地轉換成int 型
多個函數聲明可以用花括號包含在鏈接指示符複合語句中這是鏈接指示符的第二種形
式花招號被用作分割符表示鏈接指示符應用在哪些聲明上在其他意義上該花括號被忽
略所以在花括號中聲明的函數名對外是可見的就好像函數是在複合語句外聲明的一樣
例如在前面的例子中複合語句extern "C"表示函數printf()和scanf()是在C 語言中寫的
函數因此這個聲明的意義就如同printf()和scanf()是在extern "C"複合語句外面聲明的
一樣
當複合語句鏈接指示符的括號中含有#include 時在頭文件中的函數聲明都被假定是用
鏈接指示符的程序設計語言所寫的在前面的例子中在頭文件<cmath>中聲明的函數都是C
函數
鏈接指示符不能出現在函數體中下列代碼段將會導致編譯錯誤
int main()
{
// 錯誤: 鏈接指示符不能出現在函數內
extern "C" double sqrt( double );
305 第七章函數
double getValue(); //ok
double result = sqrt ( getValue() );
//...
return 0;
}
如果把鏈接指示符移到函數體外程序編譯將無錯誤
extern "C" double sqrt( double );
int main()
{
double getValue(); //ok
double result = sqrt ( getValue() );
//...
return 0;
}
但是把鏈接指示符放在頭文件中更合適在那裏函數聲明描述了函數的接口所屬
如果我們希望C++函數能夠爲C 程序所用又該怎麼辦呢我們也可以使用extern "C"
鏈接指示符來使C++函數爲C 程序可用例如
// 函數calc() 可以被C 程序調用
extern "C" double calc( double dparm ) { /* ... */ }
如果一個函數在同一文件中不只被聲明一次則鏈接指示符可以出現在每個聲明中它
也可以只出現在函數的第一次聲明中在這種情況下第二個及以後的聲明都接受第一個聲
明中鏈接指示符指定的鏈接規則例如
// ---- myMath.h ----
extern "C" double calc( double );
// ---- myMath.C ----
// 在Math.h 中的calc() 的聲明
#include "myMath.h"
// 定義了extern "C" calc() 函數
// calc() 可以從C 程序中被調用
double calc( double dparm ) { // ...
在本節中我們只看到爲C 語言提供的鏈接指示extern "C" extern "C"是惟一被
保證由所有C++實現都支持的每個編譯器實現都可以爲其環境下常用的語言提供其他鏈接
指示例如extern "Ada"可以用來聲明是用Ada 語言寫的函數extern "FORTRAN"用來
聲明是用FORTRAN 語言寫的函數等等因爲其他的鏈接指示隨着具體實現的不同而不同
所以建議讀者查看編譯器的用戶指南以獲得其他鏈接指示符的進一步信息
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章