我有一个COM对象,在C#.dll中实现,名为ComClass
,它可以提供事件。然后,我有一个C ++对象SimpleSink
,它接收从ComClass
发送的事件。事件源/接收器机制很有效。但是,当CRT调用exit()
时,我从exe_common.inl中的以下代码中获取了内存访问异常
//
// main has returned; exit somehow...
//
if (!__scrt_is_managed_app())
exit(main_result); // Exception is thrown.
异常消息的文本如下。
Cpp.exe中0x00000004处抛出异常:0xC0000005:访问冲突执行位置0x00000004。
我知道有些东西试图访问垃圾内存位置,但我不确定是什么。我研究了这个问题,我从微软那里得到了这个。
https://msdn.microsoft.com/en-us/library/ms235234.aspx
一旦公共语言运行时(CLR)进入关闭模式,本机函数对CLR服务的访问权限就会受到限制。尝试在使用/ clr编译的COM对象上调用Release时,CLR转换为本机代码,然后转换回托管代码以服务IUnknown :: Release调用(在托管代码中定义)。 CLR阻止回调到托管代码,因为它处于关闭模式。
我不确定这是否仅适用于C ++ / clr编译的COM对象或所有CLR编译的COM对象。可以说,这可能是冷酷的。我知道我可以禁用该例外,并且可能'我的生意,但这让我觉得油腻。所以,问题是,当程序关闭时,如何防止此异常?
在这里。
int main()
{
CoInitialize(NULL);
// explicit scope so that the smart pointer destructs at the correct time
{
IComClassPtr source;
HRESULT createInstance = source.CreateInstance(__uuidof(ComClass));
SinkSimple sink;
HRESULT advise = sink.DispEventAdvise(source);
try
{
source->FireEvent();
}
catch (const _com_error& ex)
{
std::cout << "Error: " << ex.Description();
}
HRESULT unadvise = sink.DispEventUnadvise(source);
}
CoUninitialize();
std::this_thread::sleep_for(std::chrono::milliseconds(100));
return 0;
}