将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异常

无需进行其他更改,例如水槽地图