[問題] 請教link lib跟dynamic load dll的差異

作者: Keitaro (動き出す時間...)   2021-03-11 00:01:38
開發平台(Platform): (Ex: Win10, Linux, ...)
Win10/Win7
編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出)
Visual Stdio 2019
額外使用到的函數庫(Library Used): (Ex: OpenGL, ...)
DirectX 12
問題(Question):
請教compile時
1. compile設定link library做linking, 程式執行時放dll
2. compile不設定link library, 程式執行時dynamic load dll
差異性
補充說明(Supplement):
這問題應該說是請教linking如何做的 並非單純C/C++的問題
我編寫一個測試DirectX 12的測試程式
IDE是VS2019, OS是win10
開發完畢後編譯完 我分別拿到win10/win7兩台測試電腦上執行
測試結果發現在win7上出了問題 因為win7上面沒有d3d12.dll這個檔案
而d3d12.lib是放在Win SDK Kit 10版底下, 我安裝VS2019就會有,
因此compile做linking當然是沒問題的
我把程式碼改為dynamic load dll的方式去做
compile的時候不再link d3d12.lib了
問題來了 原本我"以為" 所有d3d12.h裡面我有用到的API
全都必須要在我做LoadLibrary("d3d12.dll")之後
一個一個使用GetProcAddress去把每個API都load出來變成function pointer使用
但我使用dependence去檢查d3d12.dll 卻發現裡面的API
我有用到的只有一開始initial DirectX 12第一步要做的D3D12CreateDevice()
其他像是Swapchain/CommanQueue/CommonList/Fence等等 API都不在裡面
但是這些東西需要的API的確都定義在d3d12.h裡面
結果我dynamic load dll的修改 只需要改兩個地方
1. D3D12CreateDevice() 需要load d3d12.dll
2. CreateDXGIFactory2() 需要load dxgi.dll
2這一點是因為CreateDXGIFactory2()這個API在win10的dxgi.dll才有
win7底下雖然也有dxgi.dll 但比win10來的舊
所以我也無法對dxgi.lib做static link, 執行程式會因為dll/lib不match
跳出找不到CreateDXGIFactory2()的訊息
這兩個API改用GetProcAddress的方式 其他所有DX12用到的API "完、全、不、用、改"
這樣程式就跑出正確的結果了
這結果讓我非常納悶 我想法是這樣
A. 既然我已經沒有設定要link d3d12.lib
那麼我的程式應該完全不知道要去跟d3d12.dll找他的API
(雖然我不知道Linking怎麼做 但一旦設定d3d12.lib做linking
合理推測一定是會讓我的程式知道執行起來後要去找d3d12.dll)
既然D3D12CreateDevice需要GetProcAddress 其他為啥不用?
B. d3d12.dll裡面也沒有那些Swapchain等相關的API在裡面 所以是在其他的dll裡面嗎?
我在system32底下看到除了d3d12.dll以外還有兩個檔名有d3d12開頭的dll
但我用dependence沒查到相關的API
C. 如果B的推測是對的 其他那些API不在d3d12.dll裡面, 那為啥header都在d3d12.h?
其他那些API到底藏到哪一個dll裡面阿?
以上的疑惑 如果有熟悉DirectX運作原理的話還請幫小弟解惑 非常感謝…
作者: LPH66 (-6.2598534e+18f)   2021-03-11 00:05:00
如果不限 DirectX 而是比較基本的 linking 觀念的話#1LmYWwYp (Programming) 這篇文章可以先看看你這裡還需要釐清一點是這裡的 .lib 應該有兩個一個是靜態 .lib, 那就跟一般連結沒兩樣另一個是跟著 .dll 一起的 .lib, 這個才是我那篇文談的那個
作者: ofy (毆飛)   2021-03-11 01:56:00
DirectX是COM DLL(Component Object Model)....導出表找不到執行時載入的話查一下DllGetClassObject /CoCreateInstance / CoGetClassObject東西都以virtual function/VTable的方式編在DLL裡了為了方便你使用,動態連結庫幫你做了許多事
作者: b0920075 (Void)   2021-03-11 11:25:00
你舉的第二個例子已經是動態連結了吧靜態動態應該是指在執行期間的時候,不是編譯期間,若執行時還需要找symbol地址那就是動態,執行前symbol地址全都找好了就是靜態,執行時用 dlopen之類將額外的library load 進來就是dynamic loading ,windows的話不知道有沒有差你最後的留言應該是正確的
作者: Killercat (殺人貓™)   2021-03-12 11:52:00
其實你說的2 3是同一件事 只是2用系統路徑 3指定路徑er..等等 其實code寫起來不同 請忽略掉我上一行 XD
作者: descent (「雄辯是銀,沉默是金」)   2021-03-18 21:40:00
你是想知道 linker 對動態連結程式庫做了什麼手腳嗎?
作者: Lipraxde (Lipraxde)   2021-04-01 17:43:00
Linker and Loader

Links booklink

Contact Us: admin [ a t ] ucptt.com