挂钩非托管代码中的AppDomain.UnhandledException事件

问题描述

|| 我有一个用非托管C ++编写的CLR托管应用程序。 我想从非托管C ++代码订阅AppDomain.UnhandledException事件。 导入的AppDomain接口具有以下方法
HRESULT add_UnhandledException (struct _UnhandledExceptionEventHandler *value);
其中UnhandledExceptionEventHandler定义为:
struct __declspec(uuid(\"84199e64-439c-3011-b249-3c9065735adb\"))
_UnhandledExceptionEventHandler : Idispatch {}; 
我不明白如何使用此处理程序将其连接到我的回调函数。 那么,问题是如何使用它?     

解决方法

        我还没有看到任何人这样做,但这可能会帮助您考虑以下事项: 在c ++中,托管的delagate不是\“ simple \”回调,它从clr对象继承,我在c ++挂钩事件中看到的代码始终是托管的c ++。 触发未处理的异常处理程序后,接下来将发生什么取决于clr策略设置(请参见3.)。 要么进程终止(默认) appdomain已卸载 或禁用clr 吞下异常(.net 1.x中clr的行为) 您可以通过IHostPolicyManager将默认操作更改为2.2、2.3、2.4 假设您将策略设置为卸载或禁用,则可以使用IActionOnCLREvent在卸载/禁用时设置回调。 使用3)和4),您可以设置系统 在UnhandledExceptionHandler中的托管代码中清理/记录/保存(无论您需要什么) 您会收到有关以非托管代码形式卸载appdomain的通知……并执行您仍然需要做的事情。 假设这还不够(您的非托管代码需要了解异常的一些详细信息),则可以定义com接口(请参见下面的idl示例);您的托管应用程序实现了IMyApplication,而您的非托管代码IMyApplicationSink在您设置应用程序域时传递了非托管实现IMypplicationSink(您的钩子),托管应用程序必须在托管unhandledexception事件处理程序中调用该钩子:
interface IMyApplicationSink : IUnknown
{
    HRESULT UnhandeledExceptionCallback(
    [in] BSTR aString,[in] short aNumber,[in] SAFEARRAY( BYTE ) someBinaryData);
}

interface IMyApplicationControl : IUnknown
{
    HRESULT OnStart(
    [in] IPhotonApplicationSink *sink);
}
注意:有关如何获取自定义com接口的详细信息,请参见\“自定义Microsoft .NET Framework公共语言运行时\”的\“ Implement IHostControl :: SetAppDomainManager \”(当前可免费阅读)。 如果您不受托管应用程序的控制,请首先加载您控制中的应用程序-默认的appdomain-未处理的异常处理程序也将在此调用(请参阅msdn) 如果您将策略设置为吞咽(2.4),您的非托管代码将不会收到通知,clr将继续运行-您当然可以将其与自定义com界面结合使用(6.)