Zal*_*aPL 8 c++ dll manifest loadlibrary vcredist
我正在研究一个动态加载DLL作为插件的程序.我正在使用Microsoft Visual C++ 2008编译程序.但是,我们假设应该支持任何与Qt一起工作的Visual C++版本.程序目录布局如下:
| plugins/
| plugin1.dll
| plugin2.dll
| QtCore4.dll
| QtGui4.dll
| program.exe
Run Code Online (Sandbox Code Playgroud)
program.exe发现所有插件DLL文件,对它们执行LoadLibrary()并调用某个签名函数来查明它是否实际上是一个插件.这对于安装了MSVC90的vcredist的计算机非常有效.当然,要使程序在所有计算机上运行,我必须使用msvc*.dll文件和相应的清单文件重新分发它.Qt DLL还需要redist才能运行.
现在,我已经设置了cmake来根据所选的Visual Studio版本自动复制适当的redist DLL和manifest.为了简单起见,让我们继续假设我正在使用MSVC90.当redist被复制到程序目录时,布局如下所示:
| plugins/
| plugin1.dll
| plugin2.dll
| QtCore4.dll
| QtGui4.dll
| msvcm90.dll
| msvcp90.dll
| msvcr90.dll
| Microsoft.VC90.CRT.manifest (I'm also aware that this file is bugged in VS2008)
| program.exe
Run Code Online (Sandbox Code Playgroud)
关于清单文件中的错误:http://www.cmake.org/pipermail/cmake/2008-Stembertember/023822.html
具有此布局的程序现在可以在没有安装redist的计算机上运行,但插件没有加载.为了让插件加载,我必须执行以下操作之一:
plugins/目录.从清单文件中删除对msvc*.dll文件的所有引用.这有效,但它并不好,因为我必须支持不同版本的已编辑清单文件,具体取决于使用的MSVC的版本.此外,我不知道这是否会在2008年以外的Visual Studio中破坏.plugins/目录.这不需要对清单文件进行任何修改,但现在program.exe愚蠢地尝试加载msvc*.dll文件,认为它们是插件.当然,这会优雅地失败,所以不会造成太大的伤害.另一个缺点是程序包的大小增加了1 MB以上.不过,这两个问题都是我可以接受的.program.exe/ MD 都不会破坏任何东西.什么是最好的解决方案?什么是正确的解决方案?如果有多个正确的解决方案,那么这是最佳做法?我是第一个尝试这样做的人吗?
虽然这个问题仍然没有答案,但我决定选择最不会引起头痛的路线.到目前为止,我一直在使用1号解决方案,我决定坚持下去.如果CMake检测到用户使用的是与2008不同的MSVC版本,则会显示一条警告消息,指出不完全支持自动打包.
如果您的目标操作系统有 _WIN32_WINNT >= 0x0502 则您可以使用函数
SetDllDirectory()
Run Code Online (Sandbox Code Playgroud)
在加载插件之前。
将路径放置到主程序文件夹。
该调用会覆盖系统加载顺序:
因此,您可以在应用程序启动后调用该函数。在所有情况下都是安全的。祝你好运!
| 归档时间: |
|
| 查看次数: |
1316 次 |
| 最近记录: |