2009-10-29 15 views
1

我通過訪問一個DLL:更換FAR通過什麼和PASCAL通過__stdcall

int (__stdcall *Send) (char *); 
Send = (int (__stdcall *)(char *)) GetProcAddress(hmModule,"Send"); 

原來的呼叫使用:

int (FAR PASCAL *Send) (char FAR *); 
Send = (int (FAR PASCAL *)(char FAR *))GetProcAddress(hmModule,"Send"); 

有什麼缺點的,並沒有通過PASCAL FAR更換__stdcall

回答

3

刪除FAR可能會限制所有模塊在同一個段內。如果這是一個小程序,這可能很好。
編輯:但是FAR是過去的遺蹟,不適用於win32目標,並且在大多數情況下安全刪除。

更改調用約定,只會影響可能的調用這些方法的外部模塊。 (它可能也有最小對性能的影響,但我甚至不確定)。

編輯:但是WOW ...! 不!無法完成,我沒有注意到這是針對WinAPI方法的,也就是說,當調用約定很容易爲您定義時...和FAR相同,可能需要。

第二天編輯,與HYA,任擇議定書的其他詳細信息
的目標函數是在WINDEF.H定義爲

extern "C" int APIENTRY Send (LPCSTR sCmd) 

隨着它支持很多的操作系統,編譯器版本和本地定義的值,windef.h是一個組合邏輯練習[相當不錯]。與 [非MAC]的路徑,並假設WINDEF.H是在這方面的相對不變,APIENTRY歸結爲

... 
#define APIENTRY WINAPI 
... 
#define WINAPI __stdcall 

而且,由於爲相同的路徑,PASCAL也產生__stdcall第一「神祕」 (即通常非MAC,MSC編譯器8.0或更高版本(或編譯器定義_STDCALL_SUPPORTED ...)

關於FAR或什麼都沒有,對我來說不那麼清楚,但也是,windef.h宏中的大多數路徑都會導致這兩個宏產生任何東西,我認爲這是因爲編譯器會使用目標內存模型來找出什麼是短指針和長指針。無論如何,目標原型使用LPCSTR,即「遠/長」指針,這可能是編譯器生成的。同樣,對於函數本身使用的FAR修飾符,這也是不必要的,編譯器根據內存模型和/或隱式存根遠程調用。

所以,上述解釋了爲什麼,YES,所做的更改PASCAL__stdcallFAR不了了之都OK,應該導致功能性二進制。 (如果你改變編譯器和/或目標操作系統,可能需要重新檢查等等)。

非常感謝您提出這個問題,因爲這促使我重溫我在一段時間內沒見過的問題。

+0

從PASCAL更改爲StdCall不會影響性能,就好像該DLL被編譯爲允許StdCall(大多數)一樣,那麼訪問方式也不會有任何區別。希望他明白FAR指的是位於與定義的指針起點不同的段中的地址。 – Reallyethical 2009-10-29 18:30:51

+0

@合理,對,謝謝你確認沒有性能差異,並且在FAR上都可以。對於OP的確切需求,我有點困惑。大多數API都使用__stdcall(又名WINAPI),但是我從問題中得出的結論是,它目前可行,所以切換調用轉換。會明確地破壞一些東西......也許我錯過了一些' – mjv 2009-10-29 18:38:41

+0

今天下午,當我得到DLL時,我尋找一個工作示例,並在C中找到一個與舊FAR PASCAL通話。我懷疑代碼是爲以前版本的DLL編寫的。 我剛看着源和APIENTRY(=> WINAPI => __ STDCALL)用於: 外部的 「C」 INT APIENTRY發送(LPCSTR SCMD) 在WINDEF.H PASCAL定義爲__stdcall,所以它解釋爲什麼這兩個工作(?)。 – anno 2009-10-29 23:42:14