我正在编写这个库,它通过Media Foundation框架在C ++ / CLI中实现一些基本的音频播放器功能,这些功能将由托管代码使用。我可以播放音频,停止,暂停等等。对于不熟悉Media Foundation的任何人,媒体会话都会发布您可以处理通知的事件。这是通过使用IMFAsyncCallback对象在会话对象上调用BeginGetEvent来完成的。 IMFAsyncCallback定义了应该实现的方法Invoke(IMFAsyncResult)来处理事件。发生事件时,调用方法由工作线程上的会话对象调用,该工作线程具有可以查询事件信息的IMFAsyncResult对象。此结果对象由事件线程创建并拥有。
在我的Invoke实现中,每当我尝试用我传递的IMFAsyncResult对象做任何事情(包括只调用QueryInterface或其他东西)时,我都会得到一个System.AccessViolationException。我实现IMFAsyncCallback的对象是在CRT堆上分配的基本C ++类(未托管),事件发布在也在CRT堆上分配的会话对象拥有的线程上。
可能导致此异常的原因是什么?
为什么我从普通旧C ++实现的代码中抛出.NET托管异常?这就是当你有一个混合模式组件时会发生什么?
答案 0 :(得分:8)
Capture a crash dump,然后将其加载到VS 2010或WinDbg进行分析,所有内容都将被显示。 VS 2010会更容易,但WinDbg可能更有效。
由于使用WinDbg是一个更复杂的选项,我将详细说明(根据您的目标平台选择以下32位或64位版本):
.sympath srv*<SymbolCacheDir>*http://msdl.microsoft.com/download/symbols
将崩溃转储文件加载到WinDbg(文件 - >打开崩溃转储...)
为模块配置调试符号
.sympath+ <PrivatePdbDir>
将SOS个扩展名加载到WinDbg
中 .loadby sos mscorwks; * fw 2-3.5
或
.loadby sos clr; * fw 4
下载,解压缩并加载SOSEX个扩展名到WinDbg
.load <Sosex32or64Dir>\sosex
让WinDbg进行分析
!analyze -v
使用SOSEX显示当前线程堆栈(包括托管和非托管帧)
!mk
这很可能会回答你的问题。
答案 1 :(得分:1)
听起来你有一个简单的重复 - 你应该能够通过在程序运行时附加调试器来调试问题,并在访问冲突发生时捕获它。通常,库包装它并将其表示为另一种类型,并且异常的原始站点不明显。
要从Visual Studio附加到您的流程,请参阅here。当您附加到流氓进程时,请确保选择调试本机代码和托管代码的选项。确保Symbol path中的程序集和DLL的符号尽可能可用(如果它们是第三方代码,则某些符号可能不可用)。
要更改Exception配置以便在源代码中调试访问冲突,请参阅here。