作者EdisonX (閉上眼的魚)
看板C_and_CPP
標題Re: [問題] Dll export symbol的問題
時間Thu Jul 12 18:24:08 2012
推文頗長,拋磚引玉,小提幾個點,有誤請指正。
※ 引述《QQ29 (我愛阿蓉)》之銘言:
: 大家好~
: 有一個疑惑始終無法找到解答
: 因為在某些Windows平台寫程式
: 會發現 假如他提供一個
: kernel32.dll 裡面含有export a(), b(), c()三個function.
: 可是他給我們的header and lib 裡面用dumpbin 看 只有a和b...c看不到
^^^^^^
keyword , 我假定你的環境是 Windows , Compiler Visual C++。
: 對我們寫程式來說 會發現link error, 因為用到c了
如果你確信用過 c(), 知道 c() 之正確的 prototype ,
或確信該 dll - c() 功能無誤的話,
你可以直接用 LoadLibrary、GetProcAddress、FreeLibrary 這三個來完成即可,
這時根本用不到 .lib / .h;
如果你無法確信 c() 函式的品質,建議別強求。
: 但我在想
: 為啥他有能力提供 部分的 symbol包含在lib裡面? lib和dll不是一起 產生出來的嗎?
^^^^^^^^^^^^^^^^^
我不確定這段話是完全正確,
「印象中」,是有只產生 dll,或只產生 lib ,其他的都不產生,
這點沒確認過,待查證。
我不是很清楚這部份是什麼情況,甚至不知道這份 dll 是「附著他的執行檔使用」,
還是給你「開發時調用」,若是「附著他的執行檔使用」時,只需給 dll , exe 便行,
其他都是多餘的, 如一般 user 電腦大概找不到 user32.lib 這東西吧 < 沒確認 > ?
但一般 user 電腦卻大量使用了 user32.dll 這東西, 當然你的情況較明顯是開發端。
對開發端而言,不難想像的是,
一份 project , dll 在 update 時,正常會連 .lib / .h 一起更新無誤,
但這是一般 coder 會做的事。
另一種更新方式是鑑於 .lib / .h 本身只是做「引導」動作,
< 把 function entry 引到 dll 裡面去 >
所以更新時並不連 .lib / .h 一起附上,或是只附上舊版本的 .lib / .h,
很明顯的,這種更新方式對 coder 而言幾乎不會有人這麼幹!
會這麼幹的原因大概是忘了把 .lib / .h 做引導的 prototype 放進去而已,
不過大概不會有人真的那麼傻。
真正的原因我想是,那個 c() 被納成 un-document function,
undocument function 在 Win32 API 裡面也是一狗票,
不公開 prototype 、不提供 .lib / .h 讓人調用,
可能只有內部開發的人才知道怎用、有哪些危險性、穩定性如何等,
只是用 dumpbin.exe 看得到 function name 而已。
: 我在想
: 他會不會是先build出一版 含有abc三個function的lib和dll..
: 然後再把__declspec(dllexport) 從.h的c function拔掉
如我所說,只要給正確的 dll 即可,其它的 lib, .h 都只是「導引」作用,
如果你知道該 function 之 prototype , .lib / .h 本身並沒太大義意存在。
< 雖這句話有點過誇張,不過現在和你講 延遲載入 的議題可能會暴 >
提一點我覺得納悶的地方,
既然你要用 c() , 為什麼不直接找供應商要完整的 .lib / .h 或 prototype ?
如果不能提供的話我想會給你滿意理由的,這比你在這裡猜半天來得有效率多了。
: 再次build一版....然後給我們新的lib和.h 而我們使用者還是用舊的含有abc的dll
: 這是我認為的方法...但總覺得有更高深的作法
你想的方法沒錯,效果一樣,但較簡單。
另一種方式較麻煩,在生成 dll 之後,自己額外撰寫導引的 lib / header,
這些也是一般 IDE / compile 幫你做完的事。
: 另外有一個疑問...
: 有沒有能力做出
: 多個lib 其實都mapping到同一個dll?
: 謝謝
再強調,「有一種 lib」 只是導引到 dll, 而且這種 lib 可以自己寫,
所以你想把一個 dll ,依不同性質分類, 拆成數個 lib 做導引,
這又有無不可?
結論, lib / dll 並非成對產生,可以只有 lib , 也可以只有 dll,
而在調用 dll 時,為了呼叫方便,有時開發端會提供做導引的 lib, header;
但即使不提供,只要知道 dll 裡,某個 function 之 prototype,
一樣可以正常使用。
--
「自從我學了 C# , 人都變聰明 , 考試都考一百分」
「自從我學了 VB , 皮膚都變好 , 人也變漂亮了 」
「自從我學了 Java , 明顯變壯 , 個子也變高了 」
「自從我學了 C++ , 內分泌失調 , 頭都禿了... 」
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 180.177.76.161
※ 編輯: EdisonX 來自: 180.177.76.161 (07/12 18:27)
→ diabloevagto:一般要自己選擇要dll還是lib,這兩個不絕對會一起出 07/12 20:58
→ diabloevagto:現,一般我自己寫的我都只產生dll,反正.h我有 07/12 20:59
→ diabloevagto:另外我記得lib是讓coder產生static link的吧? 07/12 20:59
推 littleshan:dynamic linked dll 是需要 lib 的 (在windows上) 07/12 21:16
→ diabloevagto:不過我在windows上,不需要lib產生出的exe就能讀dll 07/12 21:28
→ EdisonX:看來那段話真的是議題了,翻過自我修養,這裡沒講細,有文可 07/12 21:51
→ EdisonX:供參閱嗎 ? 07/12 21:51
推 QQ29:謝謝~ 我消化一下... 07/13 00:25
→ QQ29:藉此請教一下 我編譯一個exe給對方run會寫缺少msvcr100.dll 07/13 00:26
→ QQ29:這不是VS2010慣了才有的dll嗎? 一般人電腦不會有這dll吧... 07/13 00:26
→ james732:上面這個問題可以用靜態連結來解決 07/13 00:30
推 QQ29:是MD改成MT嗎? 所以一般外面商用軟體也是選MT 這選項嗎 07/13 00:30
→ purincess:一般外面商用軟體可能會整個包成installer或是另外幫你 07/13 00:32
→ purincess:裝redistributable 07/13 00:32
推 purpose:我這一般人的電腦硬碟裡,莫名就有了九十幾份 msvcr*.dll 07/13 00:34
→ EdisonX:< p大應不算一般人了吧 orz > 07/13 00:59
→ EdisonX:解決方式大多如 purincess 大所言,所以vs才有什麼散佈套裝 07/13 01:00
→ EdisonX:軟體,這時候編譯模式只要用MD就行,執行檔會小很多,但若你 07/13 01:01
→ EdisonX:不想別人為了自己寫的一個小程式,就裝肥大的 red~ 套件, 07/13 01:02
→ EdisonX:這時就會考慮用 MT 模式編譯,但不論是 MT,MD,一定不會是給 07/13 01:03
→ EdisonX:debug 版的 exe,因那些 dll 沒裝 vs 大概拿不到或拿不全吧 07/13 01:03
推 littleshan:debug版的dll拿得到,但依照license是不能散布的 07/13 01:18
推 littleshan:至於外面的商用軟體是不是用MT 這點可以自行確認... 07/13 01:21
→ EdisonX:難怪 vs redistribution 一直沒 ms??d??.dll 的東西. 07/13 01:29
→ EdisonX:感謝 l 大補充。 07/13 01:30
→ Chikei:dll的lib是做load time linking用的,跟static lib不一樣 07/13 10:16
→ Chikei:只有dll就必須用LoadLibrary來做runtime linking 07/13 10:17
→ EdisonX:謝謝 Chikei 補充 :) 07/13 18:45