→ purpose:mysub 的原宣在呼叫 DLL 端不用 dllexport 寫錯但不影響 07/28 09:32
→ diabloevagto:hinstDLL = LoadLibrary("DLL.dll"); 07/28 10:23
→ diabloevagto:getID = (ptr_getID)GetProcAddress(hinstDLL, "getI 07/28 10:24
→ diabloevagto:你呼叫dll的部份不需要這樣子嗎?? 07/28 10:24
→ diabloevagto:不這樣你怎麼能夠指定到dll func? 07/28 10:24
如你所說,需要 GetProcAddress() 來取得匯出函數的位址,因為 DLL.dll 是
使用 LoadLibrary() 載入,是 explicit linking。
是原文哪段我的陳述有問題嗎?不懂為何提出此疑問
※ 編輯: purpose 來自: 124.8.137.220 (07/28 13:24)
→ diabloevagto:LoadLibrary沒問題,主要是看到你呼叫dll那段 07/28 13:56
→ diabloevagto:沒有GetProcAddress怎麼能使用呢? 07/28 13:56
你是說 mysub(10, 3); 這段吧
這裡就是用 implicit linking 的方式來載入 dllep.dll,所以不需要在原始碼中
明確使用 LoadLibrary 跟 GetProcAddress。
一開始編譯器無法 DLL 呼叫端的原始碼內找到 mysub 這個符號,所以會把其位址
隨便設,比如變成 call 0x0000 0000。
然後由 Linker 在產生 .exe 時,找出 mysub 符號來,因為此時其他 *.obj 跟 *.lib
裡,也不會有可能找到 mysub 符號,所以產生 dllep.dll 時,會附送一個
匯入用靜態函式庫,就是假的 dllep.lib。
Linker 透過 dllep.lib 找到 mysub 的位址,然後就能順利結連結出可以使用 xx.exe。
這裡的 pragma comment(lib, "dllep") 就是假指令,告訴 Linker 有 dllep.lib 這個
檔案的存在。
然後呢 Linker 從 dllep.lib 這件事得知,產生後的 xx.exe 在被人執行時,
需要相依於 dllep.dll,因此 Linker 還會在 xx.exe 檔案裡面,暗藏指示內容給
作業系統的 Loader。
當 Loader 載入 xx.exe 發現這些暗藏的指示時,就會自動把 dllep.dll 透
過 LoadLibrary() 函數去載入。
所以 xx.exe 的原始碼中,沒有也不必手動執行 LoadLibrary。
同理,這個 Loader 在順利載入 dllep.dll 成功後,還會自動更正 mysub 的位址。
該位址原本是來自 dllep.lib,沒有真正指到 dllep.dll。
此時會被 Loader 修正成相當於 GetProcAddresss() 所得到的位址。
所以 Loader 也把 GetProcAddress 省略掉了。
※ 編輯: purpose 來自: 124.8.137.220 (07/28 14:12)
※ 編輯: purpose 來自: 124.8.137.220 (07/28 14:24)
→ diabloevagto:所以一切的關鍵就是pragma comment(lib, "dllep") 07/28 14:43
→ diabloevagto:會自動做LoadLibrary 跟 GetProcAddress? 07/28 14:43
→ diabloevagto:另外請問.a跟.lib是一樣的嗎? 07/28 14:48
→ diabloevagto:我用gcc編出來的裡面有.a .dll .def 07/28 14:49
→ diabloevagto:我剛剛查了一下發現load dll有兩種方式... 07/28 15:15
→ diabloevagto:抱歉誤會了 07/28 15:15
→ purpose:google 吧 07/28 15:59
推 ofd168:我可以偷偷問一下 #pragma 是幹嘛的嗎 好像是BC再用的@@ 07/28 20:48
The #pragma directive is the method specified by the C standard for
providing additional information to the compiler.
1. 這是 C 語言標準規定的假指令,gcc, bcb, vc 都有在用
2. 提供額外資訊給 compiler 用以控制其行為用的,廣義來說 linker 也包含在內。
3. pragma 好像是來自 pragmatic? 隨便啦
4. 最常用的 pragma 指令就是 #pragma comment(lib, "xxx")
5. 微軟: http://msdn.microsoft.com/en-us/library/d9x1s805.aspx
GNU: http://gcc.gnu.org/onlinedocs/gcc/Pragmas.html
※ 編輯: purpose 來自: 124.8.137.220 (07/28 21:06)
推 EdisonX:好久沒看 purpose 發文了, 推一個 !! 07/28 21:30
推 damody:好詳細,這查書應該要查一小時了= = 07/29 17:24
推 VictorTom:推:) 07/29 22:04