3

我已经弄清楚是什么导致了这个问题,但我仍然不知道为什么——它发生在我开始fmod使用.dll. 我的测试代码是一个静态库;它指的是fmodex_vc另一个静态库,它在某个时候(虽然我不知道什么时候)决定加载它的fmodex.dll. (它和其他所有东西都在同一个目录中,所以我不知道为什么它找不到它。)据我所知,被测代码绝对不会调用 fmod 初始化函数,但也许 fmod 有一些初始化自身并加载到 dll 中的静态全局初始化程序?只有当使用它的模块中的代码被……使用时,该代码才会被拉入?

我正在使用 Visual Studio 测试框架测试非托管 C++ 代码,当我开始使用 fmod 时它停止工作:每个测试,甚至是什么都不做的“测试”测试,都会报告(为便于阅读而包装):

Unable to get type SlidersTest.UnitTest1, SlidersTest.
    Error: System.IO.FileNotFoundException: 
    The specified module could not be found.
    (Exception from HRESULT: 0x8007007E)

经过大量试验和错误,排除.cpp文件并重新添加它们,我发现只有一个测试文件引发了问题;并且只有在调用此行时才会这样做:

EntityMgr::Init();

有趣的是,如果该行在代码中 ,则所有测试都会以该消息开始失败。EntityMgr::Init()是一个很少做的函数:

EntityMgr* EntityMgr::instG = null;

void EntityMgr::Init()
{
   instG = new EntityMgr;
}

class EntityMgr
{
private:
   static EntityMgr* instG;
public:
   EntityMgr()   // does nothing beyond the default 
   {
   }

   static void Init();
   static EntityMgr* Inst() { return instG; }

   ...

   vector<Entity> entitiesG;
};

Entity, FWIW, 是一个非常普通的类,没有指针,float它的字段只有各种 s。

  • 无论我如何运行测试(从测试视图、运行选定、运行全部、从命令行运行、从测试菜单),我都会收到错误消息。
  • 尝试使用调试器进入测试失败 - 测试在调试器进入之前失败。将调试器设置为在系统异常上中断也无济于事。
  • 被测代码是一个静态 .lib。CLR 支持是/clr.
  • 哦,这只是:如果我调用一个静态实体成员函数,同样的处理。如果我将所说的静态函数移到课堂之外,同样的处理。但是,如果我将该功能移至另一个模块,那就没问题了。

如果我将调试器设置为中断任何异常,我会得到一些有趣的东西:

First-chance exception at 0x7c812aeb in vstesthost.exe: Microsoft C++ exception: HRException at memory location 0x05129890..

当然,那个位置没有源代码。这是调用堆栈:

     kernel32.dll!7c812aeb()    
    [Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]  
    kernel32.dll!7c812aeb()     
    [External Code] 
    msvcr80.dll!78158ed7()  
    msvcr80.dll!78158e34()  
    msvcr80.dll!78158047()  
    msvcr80.dll!7815850e()  
    msvcr80.dll!78158872()  
    msvcr80.dll!78158a57()  
    msvcr80.dll!78158b11()  
    ntdll.dll!7c9032a8()    
    ntdll.dll!7c90327a()    
    ntdll.dll!7c92a9ef()    
    ntdll.dll!7c90e46a()    
    kernel32.dll!7c812aeb()     
    kernel32.dll!7c812aeb()     
    kernel32.dll!7c812aeb()     
    msvcr80.dll!78139c4d()  
    msvcr80.dll!781323ff()  
    msctf.dll!74755764()    
    msctf.dll!74721557()    
    ws2_32.dll!71ab12bb()   
    ntdll.dll!7c90118a()    
    ntdll.dll!7c91b084()    
    ntdll.dll!7c90de7c()    
    ntdll.dll!7c90d04c()    
    ntdll.dll!7c90e43f()    
    kernel32.dll!7c80b713()     

这是 mstest 报告的堆栈跟踪 - 我没有从中得到任何有用的信息。

Unable to get type SlidersTest.game_EntityMgr_test, SlidersTest. Error: System.IO.FileNotFoundException: The specified module could not be found. (Exception from HRESULT: 0x8007007E)
   at System.Reflection.Assembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
   at System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
   at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
   at System.Reflection.Assembly.InternalLoadFrom(String assemblyFile, Evidence securityEvidence, Byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm, Boolean forIntrospection, StackCrawlMark& stackMark)
   at System.Reflection.Assembly.LoadFrom(String assemblyFile)
   at Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestExecuter.GetType(UnitTestElement unitTest, String type)
   at Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestExecuter.ResolveMethods().

为什么 fmod 这样做?

4

7 回答 7

1

我建议在 Dependency Walker 的 Profile 模式下运行您的应用程序 ( http://www.dependencywalker.com/ )。它可以记录所有加载 DLL 和 EXE 的尝试,以及生成的错误代码——听起来“找不到文件”错误可能来自间接依赖——可能是从链接 FMod 中提取的。

如果是这种情况,使用 Dependency Walker 分析您的应用程序将显示一次或多次失败的加载库尝试。其中之一将是对错误负责的人。

于 2009-05-14T03:06:54.753 回答
0

您能否将 Visual Studio 设置为中断所有异常,无论它们在调试期间来自何处?

听起来好像宇宙射线或有故障的硬盘驱动器已导致测试 .dll 损坏,或者您正在构建的 dll 已损坏(始终如一)。在重新安装所有 Visual Studio 之前,您可能需要要求它进行修复,这应该检查您当前安装和安装介质上的内容之间的不一致。

于 2009-04-10T15:25:20.827 回答
0

FMod .dll 如何进入您的测试目录?您是否已将其设置为将其复制到 mstest 希望进行测试的任何地方?请注意,“复制到输出目录”实际上并没有实现这一点。还有一些其他的方法,虽然我不记得它是什么。

于 2009-04-14T14:00:56.660 回答
0

我会在调试器中运行它并检查运行输出 - 特别是“加载路径\fmodex.dll”行,看看它是否正在加载正确的 dll。

在混合来自不同配置的 dll 时,我看到过类似的错误。

于 2009-05-20T15:38:58.207 回答
0

也许为该文件修改了某些属性?可能已经看过这个,但请确保所有设置都来自 Visual Studio 中的“从父级继承”。

周杰伦

于 2009-04-09T19:51:50.370 回答
0

我最好的猜测,从你到目前为止发布的内容来看,异常是在 CLR 类型加载器中的某个地方抛出的——它看起来像一个你间接依赖的程序集,要么不在 GAC 中,要么不在t 被复制到测试目录。

测试结果中是否有实际的堆栈跟踪?这可能有助于缩小它尝试加载的类型。

于 2009-04-09T20:06:11.457 回答
0

既然你说这突然发生了,我假设使用这行代码的测试以前工作得很好。这可能是一个激进的选择,但在没有其他解决方案的情况下,也许您会考虑重新安装 Visual Studio(肯定是一个漫长的过程)

于 2009-04-10T12:31:48.483 回答