今天看到inet_ntoa函數的原型,這個傳回類型實在是沒見過:
char FAR* PASCAL FAR inet_ntoa(struct in_addr in);
搜尋了一下:
1.關于FAR:(來自http://blog.csdn.net/sphone89/article/details/7184976)
FAR 是16位系統時候的概念了,代表遠指針的意思。
近指針是16位的指針,它隻表示段内的偏移位址,因而隻能對64k位元組資料段内位址進行存取。
如 char near *p;
p=(char near *)0xffff;
遠指針是32位指針,它表示段位址:偏移位址,如定義遠端指針p指向B500段的2号位址,即B500:0002,則可寫作:
char far *p;
p=(char far *)0xB5000002;
是以,遠指針可以進行跨段尋址,可以通路整個記憶體的位址。
16位系統有遠近指針之分的環境中,得告訴編譯器指針變量h_name強制使用遠指針方式。因為16位系統尋址範圍隻有2^16=64K,是以用FAR指針,再加上16位,高16位存放的是變量的段位址,低16位存放變量的段内偏移。
2.關于PASCAL(來自http://bbs.csdn.net/topics/333630中的回複)
關于__stdcall和_cdecl
(提到PASCAL)
這兩個關鍵字看起來似乎很少和我們打交道,但是看了下面的定義(來自windef.h),你一定會覺得驚訝:
#define CALLBACK __stdcall
#define WINAPI __stdcall
#define WINAPIV __cdecl
#define APIENTRY WINAPI
#define APIPRIVATE __stdcall
#define PASCAL __stdcall
#define cdecl _cdecl
#ifndef CDECL
#define CDECL _cdecl
#endif
幾乎我們寫的每一個WINDOWS API函數都是__stdcall類型的,為什麼??
首先,我們談一下兩者之間的差別:
WINDOWS的函數調用時需要用到棧(STACK,一種先入後出的存儲結構)。當函數調用完成後,棧需要清楚,這裡就是問題的關鍵,如何清除??
如果我們的函數使用了_cdecl,那麼棧的清除工作是由調用者,用COM的術語來講就是客戶來完成的。這樣帶來了一個棘手的問題,不同的編譯器産生棧的方式不盡相同,那麼調用者能否正常的完成清除工作呢?答案是不能。
如果使用__stdcall,上面的問題就解決了,函數自己解決清除工作。是以,在跨(開發)平台的調用中,我們都使用__stdcall(雖然有時是以WINAPI的樣子出現)。
那麼為什麼還需要_cdecl呢?當我們遇到這樣的函數如fprintf()它的參數是可變的,不定長的,被調用者事先無法知道參數的長度,事後的清除工作也無法正常的進行,是以,這種情況我們隻能使用_cdecl。
到這裡我們有一個結論,如果你的程式中沒有涉及可變參數,最好使用__stdcall關鍵字