从非托管代码的System.AccessViolationException?

问题描述:

我正在编写这个库,通过Media Foundation框架实现C ++ / CLI中的一些基本音频播放器功能,这些功能将由托管代码使用。我可以播放音频,停止,暂停等,只是罚款。对于不熟悉Media Foundation的任何人,媒体会话将发布您可以处理通知的事件。这通过使用IMFAsyncCallback对象调用具有会话对象的BeginGetEvent来完成。 IMFAsyncCallback定义了应该实现以处理事件的方法Invoke(IMFAsyncResult)。当事件发生时,invoke方法由具有IMFAsyncResult对象的工作线程上的会话对象调用,您可以查询事件信息。这个结果对象是由事件线程创建和拥有的。

I'm writing this library that implements some basic audio player features in C++/CLI via the Media Foundation framework that will be consumed by managed code. I can play audio, stop, pause, etc just fine. For anyone who is not familiar with Media Foundation, the media session posts events that you can handle for notifications. This is done by calling BeginGetEvent on the session object with an IMFAsyncCallback object. The IMFAsyncCallback defines the method Invoke(IMFAsyncResult) that you should implement to handle the events. When an event occurs, the invoke method is called by the session object on a work thread with an IMFAsyncResult object that you can query for the event info. This result object is created and owned by the event thread.

在我的Invoke实现中,每当我尝试和做任何事情(包括调用QueryInterface或其他)我传递的IMFAsyncResult对象,我得到一个System.AccessViolationException。我已经实现的对象IMFAsyncCallback是在CRT堆上分配的一个基本的C ++类(不是管理的),并且事件被发布在也被分配在CRT堆上的会话对象拥有的线程上。

In my implementation of Invoke, whenever I try and do anything (that includes just calling QueryInterface or something) with the IMFAsyncResult object that I am passed, I get a System.AccessViolationException. The object I have implementing IMFAsyncCallback is a basic C++ class (not managed) allocated on the CRT heap and the events are posted on a thread owned by the session object also allocated on the CRT heap.


  1. 可能导致此异常的原因是什么?

  1. What could be causing this exception?

从普通的老C ++实现的代码?

Why am I getting a .NET managed exception thrown from code that is implemented in plain old C++? Is that just what happens when you have a mixed mode assembly?


捕获崩溃转储,然后将其加载到VS 2010或WinDbg进行分析,并将全部显示。 VS 2010将会更容易,但WinDbg可能更有效。

Capture a crash dump, then load it into VS 2010 or WinDbg for analysis, and all shall be revealed. VS 2010 will be easier, but WinDbg might be more effective.

由于使用WinDbg是更复杂的选项,我会详细说明(选择32位或64根据您的目标平台的以下版本):

Since using WinDbg is the more complicated option I'll elaborate on that (choose the 32-bit or 64-bit versions of the following according to your target platform):

。 sympath srv *< SymbolCacheDir> * http://msdl.microsoft.com/download/symbols

加载故障转储文件到WinDbg(文件 - >打开崩溃转储...)

Load the crash dump file into WinDbg (File->Open Crash Dump...)

为您的模块配置调试符号

Configure debugging symbols for your modules

.sympath +< PrivatePdbDir>

载入 SOS 扩展到WinDbg

Load SOS extensions into WinDbg

.loadby sos mscorwks; * fw 2-3.5

。 loadby sos clr; * fw 4

下载,解压并加载 SOSEX 扩展到WinDbg

Download, extract and load SOSEX extensions into WinDbg

.load< Sosex32or64Dir> \sosex

让WinDbg做分析

v

使用SOSEX显示当前的线程堆栈(包括托管和非托管框架)

Use SOSEX to show the current thread stack (including both managed and unmanaged frames)

!mk

很可能会回答您的问题。

This will most likely answer your questions.