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