[问题] 请教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