Visual Studio .NET 2005 C++/ATL attribute provider

Does it make sense that __event __interface may still only use dispinterface defined in this module and not imported?

#import “libid:…” no_namespace raw_interfaces_only raw_dispinterfaces

[
coclass,
event_source(com),
default(IFoo, _FooEvents),

]
class ATL_NO_VTABLE CFoo :
public IFoo
{
public:

__event __interface _FooEvents; // Imported using #import

OK, in Visual Studio .NET 2002 the attribute provider only appeared first, this could be a problem missed while developing the stuff. 2003 version did not fix the issue. In 2005 it’s still the problem!

error C3706: ‘_FooEvents’: must be a COM interface to fire COM events
error C3335: ‘_FooEvents’: There can be at most one default interface for a coclass ‘CFoo’

There are two ways offered to solve the problem:

  1. To mix non-attributes code and implement connection point container IConnectionPointContainerImpl explicitly with a connection point map BEGIN_CONNECTION_POINT_MAP
  2. Use #import embedded_idl attribute

There is absolutely no wonder way #1 would work. But it is not interesting because attributes save our time and going non-attributed way we step back into a trouble of defining special methods to raise dispinterface events, per event.

With the other method embedded_idl has two options: emitidl and no_emitidl. emitidl which is explained as “Type information imported from the typelib will be present in the IDL generated for the attributed project. This is the default and will be in effect if you do not specify a parameter to embedded_idl.” seems to be making code compilable… But what we see is that the newly generated type library drags all imported interface definitions and duplicates them, what is obviously not any good.

no_emitidl however results in the following compiler errors:

error C3707: ‘_FooEvents::Notification’: dispinterface method must have a dispid
error C2440: ‘initializing’ : cannot convert from ‘CFoo *const ‘ to ‘ATL::IConnectionPointImpl *’

It is interesting that dispid is present and is defined quite the same way as with emitidl.

Thus, deadlock so far, have to go non-attributed way #1. And temporarily compile way #2 emitidl to get event raise code generated by Visual Studio expanding the source with compiler option /Fx

Leave a Reply