我正在重新组织传统的混合(托管和非托管DLL)应用程序,以便主应用程序段是非托管MFC,并将调用使用/ clr标志编译的C ++ DLL,它将桥接托管(C#DLL)之间的通信和非托管代码。不幸的是,我的更改导致在调用应用程序InitInstance()之前发生Access违规。这使得调试非常困难。我得到的唯一信息是以下堆栈跟踪。
> 64006108()
ntdll.dll!_ZwCreateMutant@16() + 0xc bytes
kernel32.dll!_CreateMutexW@12() + 0x7a bytes
所以,这里有一些我尝试过的观点。
- 打开Exceptions-> Win32 Exceptions-> c0000005访问冲突在Thrown时中断。我得到的最详细信息来自上面的堆栈跟踪。我已经尝试使用F10的应用程序,但它在任何断点被击中之前失败并且因上述堆栈跟踪而失败。
- 我已经删除了桥DLL,因此它只有一个返回bool的方法,并且该方法被编码为只返回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框架构建的。
答案 0 :(得分:4)
我相信我解决了我的问题。通过系统地删除每个库引用和
在应用程序代码中注释掉对该特定库的调用(非托管),我最终删除了问题库并让程序运行。这是诊断问题的一种蛮力方式,幸运的是我没有删除太多的库来解决它。如果有人通过调试器识别出库,那么我仍然会好奇。
因此,下一步是将这些库调用移动到托管代码,并通过我的桥DLL将信息传递回非托管端。顺便说一下,我将winmm.lib重新整合到项目中,它仍然有效。