引擎设计跟踪(九.14.2e) DelayLoaded DLLs (/DELAYLOAD)

时间:2022-09-20 19:40:47

关于DLL的delay load: http://msdn.microsoft.com/en-us/library/151kt790.aspx

最近在做GLES的shader compiler, 把现有的HLSL转成GLSL.

因为ShaderResource是定义在Graphics Subsystem, 而Graphics 是一个插件, 放在Tools\Plugins\下面

而转shader换过程中, shader compiler需要直接依赖Shader Resource, 所以要链接BladeGraphics.xxx

这个时候问题出现了, 如果是程序自己手动加载DLL, 那么可以指定搜索路径,

但是对于直接链接的DLL的import lib(.lib)的程序, windows系统只会在以下地方搜索依赖(http://msdn.microsoft.com/en-us/library/aa297182(v=vs.60).aspx):

1.当前进程的EXE所在文件夹

2.当前路径(cwd / GetCurrentDirectory)

3.windows 系统路径: GetSystemDirectory()

4.windows所在路径: GetWindowsDirectory ()

5.环境变量PATH中

显然我需要的路径是.\Plugins (对应的绝对路径)

但是直接执行exe的时候不能设置路径, 导致运行exe系统提示找不到该DLL.

解决办法之一是把这个插件从.\Plugins\ 下面复制到.\下面, 但是对现有的维护很不方便.

其实BladeGraphics这个插件,程序在运行时是会指定路径, 手动加载它的, 但是现在编译shader用的是它的导出类, 为了方便, 需要直接连接它的import lib, 所以执行/加载EXE时, 系统立即自动加载DLL并连接IAT

正是由于这个插件在启动后也会立马被手动加载, 所以想到了对该DLL进行延迟加载, 这样系统不会在启动程序时立即查找该DLL, 而是在第一次调用该DLL内函数时尝试加载,

而在第一次调用DLL函数的时候, 这个插件实际上已经被程序手动加载了, 系统检测到以后什么事情都不会做.

关于import lib, 是在启动时自动做了LoadLibrary, 和GetProcAddress(), 把目标DLL中所有的导出函数都连接到lib自定义的函数.因为lib不是一个Module,他会最终被静态链接到Client EXE/DLL中, 而Client EXE/DLL在调用lib中定义的函数时, 该函数则跳转到GetProcAddress()获取的, 目标DLL中的地址.