关于DLL的delay load: http://msdn.microsoft.com/en-us/library/151kt790.aspx
最近在做GLES的shader compiler, 把现有的HLSL转成GLSL.
因为ShaderResource是定义在Graphics Subsystem, 而Graphics 是一个插件, 放在ToolsPlugins下面
而转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中的地址.