Re: [問題] __stdcall 和 __cdecl的問題

看板C_and_CPP作者 (今、そこに いる僕)時間12年前 (2012/04/24 10:39), 編輯推噓0(005)
留言5則, 2人參與, 最新討論串2/2 (看更多)
※ 引述《QQ29 (我愛阿蓉)》之銘言: : 大家好 : 刻意google這兩者的差別 : 都有做簡短的介紹 : 除了name mangling會不一樣 : 好像是處理堆疊的方式會因為這兩個 "修飾字" 而不一樣 : 但這網頁特別有說一句話 : http://www.wretch.cc/blog/zevoid/216921 : "不論透過動態或靜態連結至第三方的函式庫,一定要弄清楚呼叫協定為何,不然執行時 : 期會發生堆疊被打亂的嚴重情形。" : 乍聽之下好像有道理 : 但我想一想 : 假如我做一個dll : declaration 在.h 有冠上__stdcall : 對方引用我的dll : 若他是implicit 方式 , 勢必需要我的.h檔案 : 那這樣為啥還會有她說的那句話問題產生? : 我想到唯一可能的方式 是...他刻意修改我的.h檔案 : 把__stdcall拿掉 改成__cdecl : 但這樣 name mangling後...應該會變成unresolved external symbol... : 所以我想不到他這句話會有甚麼情況會產生這問題? : 若是explicit link... : 我用GetProcAddress 也不用 (更是不知道) 對方到底是__stdcall還是__cdecl... : 這樣會出問題嗎? : 這邊也不是很明白 : 提出來請教各位 : 謝謝 : ps. 我故意在VC打 void __stdcall Foo(); 下一行打 void __cdecl Foo(); : 他會寫說我redefine了.. : 這是VC compiler刻意擋掉嗎? 照理講不是Decorate後 會不一樣 怎會產生這compile : error@@? : 感謝 call convention 除了參數傳遞方向, 也要求了參數傳遞要不要用暫存器, 跟收拾使用後 記憶體的是呼叫方還是被呼叫方, 這一切都是為了確保stack frame的完整性。 的確你用implict linkage, 那就一切沒差。但是implict不只要.h, 還要.lib。有了它們 linker跟loader會幫你把這堆東西搞定。如果對方故意亂搞你的call convention, 那的 確會unresolved symbol。不過我想沒人那麼閒才對。我想你引的那段話應該有問題。所謂 dynamic linkage(動態連結), 指的是runtime由loader把指定的外在程式碼塞入指定 基底(也許需要rebase)。而static linkage(靜態連結), 指的是compile-time由linker把 人家的lib塞進你的binary裡。但是動態連結又分成implict跟explict兩種。前者由loader 幫你載入時就作好, 後者由你自己的意志決定要不要做。那句話應該用錯術語了。 但是很多時候是要用explict linkage(loadlib rary/getprocaddr), 原因不外乎是原廠不爽給header跟lib、用異質語言的連結, 如C# 對C/C++, JNI。這時候就要自己弄了,要是你的函數指標弄錯傳遞方式,就會害stack frame collapse了。 你故意取兩個函數一樣convention不一樣,用腳指頭想也知道不會過。先不管是不是 要滙出去,萬一你自己的程式要呼叫它們,到底要呼叫誰呢?程式是經過編譯,連結兩個 時期的。call convention的分別則是在連結時期才會區開來。編譯時compiler是會把它 們當成symbol table的同一種東西的。所以錯誤是在compile-time被挑出來的。也許你覺 得說__stdcall跟__cdecl的芒果不一樣, 所以compiler應該可以分別出來。但事實上芒果 是給linker看的。這就是你會覺得奇怪的地方。 --               裸になって                                                   何が悪い?      -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 122.116.57.76 ※ 編輯: ccbruce 來自: 122.116.57.76 (04/24 10:51) ※ 編輯: ccbruce 來自: 122.116.57.76 (04/24 10:54)

04/24 22:40, , 1F
謝謝~這篇需要一些時間弄懂 感謝
04/24 22:40, 1F

04/24 22:41, , 2F
我比較不太懂 上一篇 1F的推文 跟我經歷的剛好相反@@
04/24 22:41, 2F

04/25 22:05, , 3F
你是load哪個函數呢?會不會是瞎貓碰到死耗子,我也都會掛
04/25 22:05, 3F

04/25 22:05, , 4F
stdcall/WINAPI巨集
04/25 22:05, 4F

04/25 22:06, , 5F
確實win32統一用stdcall的
04/25 22:06, 5F
文章代碼(AID): #1FbX9pj2 (C_and_CPP)
文章代碼(AID): #1FbX9pj2 (C_and_CPP)