我正在编写这个库,它通过将由托管代码使用的媒体基础框架在 C++/CLI 中实现一些基本的音频播放器功能。我可以很好地播放音频、停止、暂停等。对于任何不熟悉 Media Foundation 的人,媒体会话都会发布您可以处理通知的事件。这是通过使用 IMFAsyncCallback 对象在会话对象上调用 BeginGetEvent 来完成的。 IMFAsyncCallback 定义了您应该实现来处理事件的方法 Invoke(IMFAsyncResult)。当事件发生时,工作线程上的会话对象将调用 invoke 方法,并使用可查询事件信息的 IMFAsyncResult 对象。该结果对象由事件线程创建并拥有。
在我的 Invoke 实现中,每当我尝试使用传递的 IMFAsyncResult 对象执行任何操作(包括仅调用 QueryInterface 或其他操作)时,都会收到 System.AccessViolationException。我实现 IMFAsyncCallback 的对象是分配在 CRT 堆上的基本 C++ 类(非托管),事件发布在同样分配在 CRT 堆上的会话对象拥有的线程上。
什么可能导致此异常?
为什么我会从用普通旧式 C++ 实现的代码中抛出 .NET 托管异常?当您使用混合模式装配时,是否会发生这种情况?
捕获故障转储,然后加载到VS 2010或WinDbg中进行分析,一切就都显现出来了。 VS 2010 会更容易,但 WinDbg 可能更有效。
由于使用 WinDbg 是更复杂的选项,我将对此进行详细说明(根据您的目标平台选择以下版本的 32 位或 64 位):
- 下载并安装Windows 调试工具
- 配置调试符号微软符号服务器
.sympath srv*<SymbolCacheDir>*http://msdl.microsoft.com/download/symbols
- 将故障转储文件加载到 WinDbg 中(文件 -> 打开故障转储...)
- 为模块配置调试符号
.sympath+ <PrivatePdbDir>
.loadby sos mscorwks; * fw 2-3.5
or
.loadby sos clr; * fw 4
.load <Sosex32or64Dir>\sosex
!analyze -v
- 使用SOSEX显示当前线程堆栈(包括托管帧和非托管帧)
!mk
这很可能会回答您的问题。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)