将COM事件从C#激发到C+的正确方法是什么+; 我们有一个项目,其中有很多遗留代码在C++中(使用ATL)、VB6和最近的C*y.< /P> 我们最近将一个组件从C++移植到C语言,它触发了C++、VB6和C语言中的组件所处理的事件。 理论上,这一切都在运行,但触发事件会产生大量System.NotImplementedException
我已经修改了触发事件的代码,以便它单独调用每个事件处理程序,这样一个对象的异常不会阻止它在下一个对象中调用事件处理程序将COM事件从C#激发到C+的正确方法是什么+; 我们有一个项目,其中有很多遗留代码在C++中(使用ATL)、VB6和最近的C*y.< /P> 我们最近将一个组件从C++移植到C语言,它触发了C++、VB6和C语言中的组件所处理的事件。 理论上,这一切都在运行,但触发事件会产生大量System.NotImplementedException,c#,c++,com,com-interop,atl,C#,C++,Com,Com Interop,Atl,我已经修改了触发事件的代码,以便它单独调用每个事件处理程序,这样一个对象的异常不会阻止它在下一个对象中调用事件处理程序 if ( GeneratedChannelChange != null ) { // Invoke each handler separately, so that an exception in one invokation does not prevent us calling the next one. foreach ( GeneratedChannelChan
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++代码也忽略了调用函数返回的错误。
这似乎工作正常,但我对它生成的大量异常感到不满意。在调试器中运行时,这也会降低性能我认为只有在C++类中处理事件时才会抛出异常。这是使用ATL类IDispEventSimpleImpl实现的。我发现,IDispEventSimpleImpl没有实现函数GetIDsOfNames。此函数肯定正在被调用,并返回E_NOTIMPL
<> P>新C代码是调用函数gTiDSPONDEX,但旧C++代码没有? 如果是这样的话,在使用IDispEventSimpleImpl的类中是否有简单的方法来实现函数GetIDsOfNames如果我的分析是错误的,在C++中(作为事件源)和C++(作为事件接收器),是否有一种“正确”的方法来实现事件逻辑? 我想我已经解决了这个问题,用IDispentSimpleImpl替换了IDispentSimpleImpl
这或多或少是一种替换,但它确实需要对类型库的引用 ATL类继承多个基类,包括一个定义为WorkspaceEventSink的基类class ATL_NO_VTABLE CImportChannels :
...
public WorkspaceEventSink,
...
{
...
}
这以前被定义为
typedef IDispEventSimpleImpl< 42, CImportChannels, &DIID_ICs3WorkspaceEvents> WorkspaceEventSink ;
typedef IDispEventSimpleImpl<42,CImportChannels,&DIID_ICs3WorkspaceEvents>WorkspaceEventSink;
我已将定义更改为
typedef IDispEventImpl< 42, CImportChannels, &DIID_ICs3WorkspaceEvents, &LIBID_McAnalEventsNET, 1, 0 > WorkspaceEventSink ;
typedef idispentimpl<42,CImportChannels,&DIID_ICs3WorkspaceEvents,&LIBID_McAnalEventsNET,1,0>WorkspaceEventSink;
除了将IDispEventSimpleImpl更改为IDispevenTempl之外,我还添加了类型库的GUID以及主要版本号和次要版本号
最初,我尝试将主要版本号和次要版本号保留,但这导致了一个类型库not registered异常
无需进行其他更改,例如水槽地图