Re: [問題] __stdcall 和 __cdecl的問題
※ 引述《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
04/24 22:41, 2F
→
04/25 22:05, , 3F
04/25 22:05, 3F
→
04/25 22:05, , 4F
04/25 22:05, 4F
→
04/25 22:06, , 5F
04/25 22:06, 5F
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 2 之 2 篇):