可以看出,函數(shù)的定義和函數(shù)指針的定義非常類(lèi)似。
一般的化,為了簡(jiǎn)化函數(shù)指針類(lèi)型的變量定義,提高程序的可讀性,我們需要把函數(shù)指針類(lèi)型自定義一下。
回調(diào)函數(shù)可以象普通函數(shù)一樣被程序調(diào)用,但是只有它被當(dāng)作參數(shù)傳遞給被調(diào)函數(shù)時(shí)才能稱(chēng)作回調(diào)函數(shù)。
被調(diào)函數(shù)的例子:
用戶(hù)在調(diào)用上面的函數(shù)時(shí),需要自己實(shí)現(xiàn)一個(gè)pcb類(lèi)型的回調(diào)函數(shù):
然后,就可以直接把fCallback當(dāng)作一個(gè)變量傳遞給GetCallBack,
如果賦了不同的值給該參數(shù),那么調(diào)用者將調(diào)用不同地址的函數(shù)。賦值可以發(fā)生在運(yùn)行時(shí),這樣使你能實(shí)現(xiàn)動(dòng)態(tài)綁定。參數(shù)傳遞規(guī)則到目前為止,我們只討論了函數(shù)指針及回調(diào)而沒(méi)有去注意ANSI C/C++的編譯器規(guī)范。許多編譯器有幾種調(diào)用規(guī)范。如在Visual C++中,可以在函數(shù)類(lèi)型前加_cdecl,_stdcall或者_(dá)pascal來(lái)表示其調(diào)用規(guī)范(默認(rèn)為_(kāi)cdecl)。C++ Builder也支持_fastcall調(diào)用規(guī)范。調(diào)用規(guī)范影響編譯器產(chǎn)生的給定函數(shù)名,參數(shù)傳遞的順序(從右到左或從左到右),堆棧清理責(zé)任(調(diào)用者或者被調(diào)用者)以及參數(shù)傳遞機(jī)制(堆棧,CPU寄存器等)。
將調(diào)用規(guī)范看成是函數(shù)類(lèi)型的一部分是很重要的;不能用不兼容的調(diào)用規(guī)范將地址賦值給函數(shù)指針。例如:
// 被調(diào)用函數(shù)是以int為參數(shù),以int為返回值__stdcall int callee(int);
// 調(diào)用函數(shù)以函數(shù)指針為參數(shù)void caller( __cdecl int(*ptr)(int));
// 在p中企圖存儲(chǔ)被調(diào)用函數(shù)地址的非法操作__cdecl int(*p)(int) = callee; // 出錯(cuò)
指針p和callee()的類(lèi)型不兼容,因?yàn)樗鼈冇胁煌恼{(diào)用規(guī)范。因此不能將被調(diào)用者的地址賦值給指針p,盡管兩者有相同的返回值和參數(shù)列例子:
參考自 http://www.shnenglu.com/jjbird/articles/3364.html
Powered by: C++博客 Copyright © silentneil