3

我正在重新组织一个旧的混合(托管和非托管 DLL)应用程序,以便主应用程序段是非托管 MFC,它将调用使用 /clr 标志编译的 C++ DLL,该标志将桥接托管(C# DLL)和非托管代码之间的通信. 不幸的是,我的更改导致在调用应用程序 InitInstance() 之前发生访问冲突。这使得调试非常困难。我得到的唯一信息是以下堆栈跟踪。

>   64006108()  
ntdll.dll!_ZwCreateMutant@16()  + 0xc bytes 
kernel32.dll!_CreateMutexW@12()  + 0x7a bytes   

所以,这里有一些我试过的场景。
- 打开 Exceptions->Win32 Exceptions->c0000005 Access Violation 以在抛出时中断。我得到的最详细信息仍然来自上面的堆栈跟踪。我已经使用 F10 尝试了该应用程序,但它在任何断点被命中之前失败,并且由于上述堆栈跟踪而失败。

- 我已经删除了桥接 DLL,因此它只有一个返回布尔值的方法,并且该方法被编码为只返回 false(不调用 C# 代码)。

bool DllPassthrough::IsFailed() { return false; }

如果使用 /clr 标志编译已存根的 DLL,则应用程序将失败。如果编译时没有 /clr 标志,则应用程序运行。

- 我使用 Visual Studio 向导为多文档应用程序创建了一个存根 MFC 应用程序,并调用 DllPassthrough::IsFailed()。即使使用用于编译 DLL 的 /clr 标志,这也会成功。

- 我已经尝试在 winmm.lib 上执行手动 LoadLibrary,如下面的注释Access violation when using c++/cli中所述。应用程序仍然失败。

所以,我的问题是如何解决这个问题?任何提示、策略或以前的事件。而且,如果做不到这一点,我如何才能获得有关导致访问异常的代码段或库的更多信息?如果我尝试更多涉及的解决方法,例如进行 LoadLibrary 调用,我想将其缩小到失败的库。

谢谢。顺便说一句,我们使用的是 Visual Studio 2008,并且该项目是针对托管部分的 .NET 2.0 框架构建的。

4

1 回答 1

4

我相信我解决了我的问题。通过系统地删除每个库引用并在应用程序代码(非托管)中注释掉对该特定库的调用,我最终删除了问题库并让程序运行。这是诊断问题的蛮力方法,幸运的是我不必删除太多库来解决它。如果可以通过调试器识别库,如果有人有评论,我仍然会很好奇。
因此,下一步是将这些库调用移动到托管代码,并通过我的桥接 DLL 将信息传递回非托管端。顺便说一句,我将 winmm.lib 重新集成到项目中,它仍然有效。

于 2010-04-15T19:29:50.147 回答