我们有一个项目,其中包含许多C ++(使用ATL),VB6和最近的C#遗留代码。我们最近将组件从C ++移植到了C#,该事件触发由C ++,VB6和C#中的组件处理的事件。从理论上讲,一切正常,但是触发事件会生成许多System.NotImplementedExceptions。我已经修改了触发事件的代码,以便它分别调用每个事件处理程序,这样一个对象的异常不会阻止它在下一个对象中调用事件处理程序。if ( GeneratedChannelChange != null ){ // Invoke each handler separately, so that an exception in one invokation does not prevent us calling the next one. foreach ( GeneratedChannelChangeEventHandler del in GeneratedChannelChange.GetInvocationList() ) { try { del.Invoke ( GenChan, ChangeMask ) ; } catch ( Exception ) {} }}实际上,由ATL向导生成的原始C ++代码也忽略了invoke函数返回的错误。这似乎工作正常,但是我对它产生的大量异常不满意。在调试器中运行时,这也会降低性能。我认为只有在C ++类中处理事件时才会引发异常。这是使用ATL类IDispEventSimpleImpl实现的。我发现的是,IDispEventSimpleImpl没有实现功能GetIDsOfNames。肯定会调用此函数,并且它将返回E_NOTIMPL。可能是新的C#代码正在调用函数GetIDsOfNames,而旧的C ++代码没有吗?如果是这样,是否有任何简单的方法可以在使用IDispEventSimpleImpl的类中实现功能GetIDsOfNames?如果我的分析是错误的,是否有“正确”的方法在C#(作为事件源)和C ++(作为事件接收器)中实现事件逻辑?
1 回答
偶然的你
TA贡献1841条经验 获得超3个赞
我想,我已经解决了这一问题,通过更换IDispEventSimpleImpl的与IDispEventImpl的。
这或多或少是一个即插即用的替代品,但是它确实需要引用类型库。
ATL类继承了多个基类,包括一个定义为WorkspaceEventSink的基类。
class ATL_NO_VTABLE CImportChannels :
...
public WorkspaceEventSink,
...
{
...
}
先前定义为
typedef IDispEventSimpleImpl< 42, CImportChannels, &DIID_ICs3WorkspaceEvents> WorkspaceEventSink ;
我已将定义更改为
typedef IDispEventImpl< 42, CImportChannels, &DIID_ICs3WorkspaceEvents, &LIBID_McAnalEventsNET, 1, 0 > WorkspaceEventSink ;
除了将IDispEventSimpleImpl更改为IDispEventImpl外,我还添加了类型库的GUID及其主要版本号和次要版本号。
最初,我尝试不使用主要版本号和次要版本号,但这导致了类型库未注册的异常。
无需进行其他更改(例如对接收器映射进行更改)。
- 1 回答
- 0 关注
- 298 浏览
添加回答
举报
0/150
提交
取消