我目前正在 Visual Studio 2015 中制作一个 OpenGL 应用程序,并且已成功链接和包含了 GLFW、GLEW 等的所有内容。
但是当我运行我的应用程序时,我需要包含glew32.dll
,完全没有问题。我只需获取 x64 dll 并将其添加到项目文件夹即可。但是现在,当我在 32 位模式下运行我的程序时,它会中断,如果我要在 64 位程序上使用 32 位 dll,反之亦然。唯一便宜的解决方法是将特定于体系结构的 dll 包含在构建文件夹中。
有没有办法可以在特定于体系结构的基础上包含 dll,因为我想以如下形式存放我的结果程序:
程序目录
- 游戏程序
- 游戏_x64.exe
- x64(文件夹)
- glew32.dll
- x32(文件夹)
- glew32.dll
如果这样的事情不可能的话,我非常乐意将一个glew32.dll
放在glew32_x64.dll
一个文件夹中,但这可能永远不会发生,因为库没有寻找新的 dll......
答案1
文章动态链接库搜索顺序实际上也有一些关于如何改变应用程序查找 DLL 的方式的内容。也就是说,它引用SetDllDirectory
和LoadLibraryEx
甚至更多。
答案2
解决这个问题有多种方法。
构建系统
MSBuild 有许多无法通过 Visual Studio GUI 控制的功能。几乎可以在任何地方使用变量,有时也可以使用条件。
您可以在.vcxproj
文件(仅 XML)中声明条件块,像这样:
<Choose>
<When Condition="'$(Platform)' == 'Win32'">
<ItemGroup>
<Reference Include="SomeProject">
<HintPath>..\Libraries\x86\SomeProject.dll</HintPath>
</Reference>
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<Reference Include="SomeProject">
<HintPath>..\Libraries\x64\SomeProject.dll</HintPath>
</Reference>
</ItemGroup>
</Otherwise>
</Choose>
还有其他解决方案,例如这个:
<Content Include="..\..\MyContentFiles\**\*.*">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
它不能直接解决您的问题,但可以让您进一步了解 MSBuild 的功能。
我曾经有一个针对非常相似的问题的解决方案(使用调试/发布版本引用.NET 的本机库),但它仍留在我以前的雇主那里。
如果您觉得 MSBuild 限制太多,您可以随时创建后构建任务。
该解决方案也可以作为下面提到的双架构单独目录解决方案的一部分,因为它有助于更好地自动化构建过程。
DLL 预加载
调用LoadLibrary
或LoadLibraryEx
并手动加载正确的 DLL。这只有在您在 OS 加载程序自动加载 DLL 之前拥有控制权时才有可能。
独立目录
将启动器放在顶层目录中。然后,将 x86 和 x64 版本放入单独的目录中:
.\Launcher.exe
.\x64\Game.exe
.\x64\glew32.dll
.\x86\Game.exe
.\x86\glew32.dll
搜索路径
我认为,在完全受控的环境中这完全没有必要。