在win32加载器之前执行代码?

时间:2016-04-20 09:05:28

标签: c++ winapi visual-studio-2015

我有一个VisualStudio单元测试项目 - Tests.exe。此exe取决于分别生成AB的dll项目A.dllB.dll

当我执行Tests.exe时,它无法运行,因为AB未复制到exe的输出目录。我想避免这样做,因为有100个exes和dlls。

相反,我想在Windows加载器之前执行某些方法,以便调用SetDllDirectory API来添加AB dll所在的目录。

所以TL; DR - 如果一个exe缺少一个dll,我怎么能在" N.dll丢失之前执行SetDllDirectory"错误?

3 个答案:

答案 0 :(得分:0)

使用延迟加载。从技术上讲,这不能回答你的问题 - Win32加载器只有在加载了你的可执行文件导入的所有DLL之后才会调用你的入口点。但是通过延迟加载,编译器会发出即时执行的LoadLibraryGetProcAddress调用。您甚至可以自定义LoadLibrary个调用,并以您想要的任何方式获取DLL HMODULE

答案 1 :(得分:0)

  

[我]一个exe缺少一个dll,如何在“N.dll缺失”错误之前执行SetDllDirectory

基本上你不能。该加载器代码在任何用户代码之前执行,这是您可以尝试强制进入该代码段的限制。您可以在库部分中“初始化”初始化代码,但它仍然不允许您控制加载dll的位置。

如何解决这个问题?

最简单的方法是在执行测试之前确保将dll和/或exe构建到(或复制到)所需位置。

构建解决方案;

  • VS允许您标记依赖项目,然后将dll复制到输出文件夹 - 您可以执行此操作。此外,如果项目是单个解决方案的一部分,请为每个配置设置公共构建输出文件夹。
  • 如果解决方案未配置为包含所有项目,则可以添加“预构建”步骤以将所需的依赖项复制到输出文件夹,或者添加“post-build”以将exe复制到以下位置:包括执行测试exe之前的所有依赖项。或者,构建到公共文件夹;按惯例或环境变量定义。

运行时解决方案;

    路径修复后
  • Delay load the dll。对于每个延迟加载的dll,将/delayload switch添加到命令行;

    /DELAYLOAD:A.dll
    
  • 您还可以直接使用LoadLibraryGetProcAddress等函数来控制dll的加载,直到稍后,您也可以控制它们的加载位置。这可能需要某种“存根”来将dll函数暴露为C兼容函数,因此它可能远非理想,但它是可能的。

答案 2 :(得分:0)

Visual Studio对C ++项目表现不佳的一个原因是产生“可运行”的输出。

我发现解决这个问题的最简单方法是设置一个所有二进制文件都构建到的解决方案级输出文件夹。这可确保所有EXE和DLL位于同一位置,并且可以将所需的任何其他资产部署到同一文件夹中。

tl; dr - 不是将dll复制到单元测试exe文件夹 - 而是将单元测试的输出路径设置为dll的文件夹。