全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1217
推到 Plurk!
推到 Facebook!

請問有關 calling convention options 的問題

尚未結案
arisaka_matsuri
高階會員


發表:25
回覆:205
積分:231
註冊:2003-10-19

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-12-21 21:55:14 IP:218.166.xxx.xxx 未訂閱
我有一個關於BCB函數(function)宣告時所用的修飾字的問題,請教各位大大 一般來說,BCB中函數都會加上 __fastcall 修飾字,但是最近我在寫程式時,會有寫好的函數卻沒辦法真正傳入、傳出值的問題。trace了好幾次,都是同樣的情況,比方說:
void __fastcall function_name(Graphics::TBitmap* pBMP, long index)
{
  ...
}
呼叫function_name(pBitmap, 0),但是index的值卻沒有真正傳入(index的值會是一個不確定的值,但不是0),怎麼會這樣? 如果把修飾字__fastcall拿掉,或是改用__stdcall,就一切正常。於是我查了BCB的說明,有關calling convention options的部分。看是看的懂,不過為什麼會出現上述的問題呢?在__fastcall的說明中提到,__fastcall使用暫存器EAX, EDX, ECX傳遞前3個參數,除了速度快和使用上的限制,會有可能造成參數無法傳遞的情況嗎?能否解釋一下呢?
ENIX007
高階會員


發表:28
回覆:274
積分:185
註冊:2003-11-27

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-12-22 15:41:32 IP:210.243.xxx.xxx 未訂閱
arisaka_matsuri您好: 這是之前在網路上找到的文章,希望能有所幫助,由於我已經無從得知它原始 連結,因此用引言的方式節錄出來:    
引言: C Builder的命名規則 除了前面提到的 __declspec編譯指令之外,在C Builder尚有几种修飾字會影響到函數的命名, 它們就是 __cdecl,__stdcall,__pascal,__fastcall四個修飾字。為了了解該修飾字對於函式命名的影響,我們可以用以下的程式來測試之:
#ifndef _DLLNAME01_H_     #define _DLLNAME01_H_     #ifndef DLLNAME     #define EXTERN __declspec(dllimport)     #else     #define EXTERN __declspec(dllexport)     #endif     EXTERN void DllName01(void);     EXTERN void _stdcall DllName02(void);     EXTERN void _cdecl DllName03(void);     EXTERN void _pascal DllName04(void);     EXTERN void _fastcall DllName05(void);     };     #endif    以上為程式的定義,同時我們可以在 .CPP檔中撰寫相對應的空函式,然後將其編譯成DLL檔,再利用TDUMP.EXE或是VC   內的DUMPBIN.EXE來觀察其內容,由於TDUMP會將函式命名解碼,反而會使混淆原來的名稱,因此以下的輸出是由DUMPBIN.EXE得來。         函式定義 DLL內的函式名 摘要說明     void DllName01(void) @DllName01$qv 因為是CPP程式碼     void _stdcall DllName02(void) @DllName02$qqsv 所以函式名都被修     void _cdecl DllName03(void) @DllName03$qv 飾過。     void _pascal DllName04(void) @DLLNAME04$QV     void _fastcall DllName05(void) @DllName05$qqrv     以上結果是否令你丈二金鋼、摸不著頭緒。這是因為我們的程式名稱若以CPP為延伸名,C  Builder會以C   特有的命名方式來為函式命名,這种命名方式會在函式名稱後加上其使用參數的性質,如參數類別等。這在C   中有一個特別的名稱,叫做mangled name,這是一种為了要實作出多載函式所發出的命名規則。(注:在C   中Add(int) 和Add(double) 可以同時存在,因此必須在object code區分之)。同時這种命名方式由於各個編譯器厂商使用的方式各不相同,因此在撰寫DLL時要避免使用之。為了要避開以上問題,我們改以下列的宣告方式:     #define _DLLNAME01_H_     #ifndef DLLNAME     #define EXTERN __declspec(dllimport)     #else     #define EXTERN __declspec(dllexport)     #endif     extern "C" {     EXTERN void DllName011(void);     EXTERN void _stdcall DllName022(void);     EXTERN void _cdecl DllName033(void);     EXTERN void _pascal DllName044(void);     EXTERN void _fastcall DllName055(void);     };     #endif    其中extern "C" {櫋櫋.}; 是用來告訴編譯器使用C的命名方式,不要使用C   的mangled name。若是其中只有一個函式時,你可以直接以下列方式宣告之:     extern "C" void __stdcall ShowImage();     現在我們可以檢視除去mangled name後的函式名稱:    函式定義 DLL內的函式名 摘要說明     void DllName01(void) _DllName01 名稱加底線     void _stdcall DllName02(void) DllName02 名稱未變     void _cdecl DllName03(void) _DllName03 名稱加底線     void _pascal DllName04(void) DLLNAME04 名稱大寫     void _fastcall DllName05(void) @DllName05 名稱加@     以上我們可得知,在未加修飾字時和使用_cdecl修飾字時的名稱是一樣的。而 _pascal修飾字所產生的函式名則和16位元的標准DLL 函式名相同(這在VC   是不被接受的),__fastcall的函式名稱則加上 @。    其中在WIN32中使用最多的是 _stdcall修飾字,這也是你要撰寫一個可以和其他語言共同使用時所使用的修飾字,其次則為 __cdecl修飾字,這是用來傳送不定參數型別的函式如printf、sprintf等使用的。其餘兩者几乎在DLL沒有机會使用。     結論:由上可知,在C  Builder中撰寫DLL時必須注意以下事項:     使用 __declspec(dllimport)及 __declspec(dllexport)的標准型式。 
注意C   的函式名稱編碼(mangled name)。 
注意修飾字的使用。除非使用不定參數的函式,否則必使用 __stdcall修 
飾字。     (4) 不要把 __declspec的使用和 __stdcall混淆了。此二者并沒有絕對的相關性。即使是程式老手都可能栽在此處,切記,切記!     怎麼樣,在看完了以上的介紹後,是否有晃然大悟的感覺。在了解以上的規則後,今後不論在撰寫或是使用DLL時遭遇連結的問題時,應該難不倒你吧!
程式迷人之處,在於邏輯思考,然而卻也是惱人之處~~ 發表人 - taishyang 於 2003/12/22 18:48:08
------
程式迷人之處,在於邏輯思考,然而卻也是惱人之處~~
ENIX007
高階會員


發表:28
回覆:274
積分:185
註冊:2003-11-27

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-12-22 15:51:53 IP:210.243.xxx.xxx 未訂閱
貼完這篇,又想到另一篇 在 href="http://delphi.ktop.com.tw/topic.php?TOPIC_ID=33420">http://delphi.ktop.com.tw/topic.php?TOPIC_ID=33420 有一篇shaofu大大的回應,後半段也有對此的詳細說明 請享用~~ 程式迷人之處,在於邏輯思考,然而卻也是惱人之處~~
------
程式迷人之處,在於邏輯思考,然而卻也是惱人之處~~
系統時間:2024-05-18 5:40:46
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!