C++多態(tài)與虛擬之C++編譯器對函數(shù)名的改編(Name?Mangling)
如果函數(shù)名稱都相同(也就是被overloaded),編譯器在面對你的函數(shù)喚起動作時,究竟是如何確定調(diào)用哪個函數(shù)實體呢?事實上,編譯器把所有同名的overloaded functions視為不同的函數(shù),并且以特殊方式對它們的函數(shù)名稱做了手腳,以四個Add()函數(shù)為例:
int Add(int a, int b); long Add(long a, long b); double Add(double a, double b); float Add(float a, float b);
Visual C++編譯器真正為這四個函數(shù)所編碼出來的函數(shù)名稱是:
?Add@@YAHHH@Z ?Add@@YAJJJ@Z ?Add@@YANNN@Z ?Add@@YAMMM@Z
再以 CPoint 的兩個 x() 為例:
class CPoint { public: ... float x(); void x( float xval ); };
編譯器真正為它們編出來的函數(shù)名稱是(其中包含class名稱,參數(shù)個數(shù)和參數(shù)類型):
?x@CPoint@@QAEMXZ ?x@CPoint@@QAEXM@Z
這樣的“名稱改編”行為稱為“name manging”。讓人遺憾的是,不同編譯器有著不同的name manging作法。這當(dāng)然不好,表示我以Microsoft C++編譯出來的程序沒辦法調(diào)用一個以Borland C++編譯器完成的函數(shù)。換句話說,函數(shù)的名稱并不存在著binary standard,這就嚴(yán)重影響了software components的發(fā)展。Naming Mangling 不只用于overloaded functions身上,C++程序中所有的global函數(shù)以及classes中的所有members,都會被施以naming mangling手術(shù)。如果要抑制naming mangling的作用,就必須加上關(guān)鍵字extern“C”以修飾。
extern "C":對于程序員來說,通常不需要關(guān)心名稱改編(Name Mangling)這個問題。但是,當(dāng)你的C++程序需要導(dǎo)出某些功能供其他程序或庫使用時,名稱改編就會成為一個問題。在C++程序中,可以導(dǎo)出的東西主要是函數(shù)和類。雖然也可以導(dǎo)出數(shù)據(jù),但根據(jù)“數(shù)據(jù)封裝”的原則,導(dǎo)出數(shù)據(jù)是非常罕見且應(yīng)該避免的做法。 無論類是否被導(dǎo)出,它們的名稱都會被改編。但是,對于函數(shù)來說,當(dāng)我們試圖導(dǎo)出它們時,我們不希望編譯器對它們進(jìn)行名稱改編。這是因為我們不希望這些函數(shù)的使用者被限制使用“與函數(shù)設(shè)計者相同的開發(fā)工具”。畢竟,目前各家C++編譯器廠商并沒有協(xié)調(diào)出一個統(tǒng)一的名稱改編方法。 因此,對于即將導(dǎo)出的函數(shù),為了抑制名稱改編的作用,我們必須加上特殊的修飾詞`extern "C"`。這樣做可以讓編譯器知道這些函數(shù)應(yīng)該使用C風(fēng)格的鏈接,從而避免名稱改編。這樣,其他語言或庫就可以正確地調(diào)用這些函數(shù)了。例如:
extern "C" int Add(int a, int b);
在Windows DLLs中,使用C++編寫的DllMain()等callback函數(shù)需避免C++編譯器進(jìn)行name mangling,因此需使用extern "C"。這樣可以確保函數(shù)名稱和格式固定,便于系統(tǒng)回呼。
extern "C" int APIENTRY 7 DllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved) { ... }
到此這篇關(guān)于C++多態(tài)與虛擬之C++編譯器對函數(shù)名的改編(Name Mangling)的文章就介紹到這了,更多相關(guān)C++編譯器對函數(shù)名的改編內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MySQL系列教程之使用C語言來連接數(shù)據(jù)庫
c語言操作Mysql數(shù)據(jù)庫,主要就是為了實現(xiàn)對數(shù)據(jù)庫的增、刪、改、查等操作,下面這篇文章主要給大家介紹了關(guān)于MySQL系列教程之使用C語言來連接數(shù)據(jù)庫的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09用while判斷輸入的數(shù)字是否回文數(shù)的簡單實現(xiàn)
這篇文章主要介紹了用while判斷輸入的數(shù)字是否回文數(shù)的簡單實現(xiàn),需要的朋友可以參考下2014-02-02C語言數(shù)據(jù)結(jié)構(gòu)之vector底層實現(xiàn)機制解析
向量(Vector)是一個封裝了動態(tài)大小數(shù)組的順序容器(Sequence?Container)。跟任意其它類型容器一樣,它能夠存放各種類型的對象??梢院唵蔚恼J(rèn)為,向量是一個能夠存放任意類型的動態(tài)數(shù)組2021-11-11