问题描述
||
我有一个用非托管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.)