Hi,

I have spent the last 2 days on this issue and this is my last resort. I would really, really appeciate anyone's help.

I have found plenty of articles that show you how to raise events in a managed DLL (C# in my case) and sink them in unmanaged VC++ through COM/ATL. As far as I can tell, I am doing everything EXACTLY how they specify, but I get an error when I try to call DispEventAdvise on my VC++ event handler to handle the managed DLL server's event.

Drilling down to find exactly where the error occurs, I find that in the ATL library, it dies in AtlAdvise, at the point it does "hRes = pCPC->FindConnectionPoint(iid, &pCP);"

From what I've read, I'm thinking this means that either the SINK_MAP I've defined in my VC++ event handler doesn't match up to the object whose events I'm trying to handle, or there is no IConnectionPoint interface. The problem is I don't see how that is possible, as everything seems exactly like it should. My only concern is that .tlh file doesn't actually show the event method in the IDispatch interface. I'm not sure if its not suppoed to be here, but if it is, I guess that would explain why this isn't working.

To give some more background, here is the snippets of my code that relate to this:


My C# class that raises the event (SAPIEngine.cs)
--------------------------------------------------
namespace SAPITest.SpeechRecognitionEngine.SAPI
{
public delegate void RuleRecognizedDelegate();


[GuidAttribute("DCFB16E7-7DA3-4f72-8F9F-9378D2620C48"), ClassInterface(ClassInterfaceType.None), ComSourceInterfaces(typeof(RuleRecognizedEvents))]
public class SAPISpeechRecognitionEngine : ISAPISpeechRecognitionEngine
{
public event RuleRecognizedDelegate RuleRecognizedEvent;
}

public void raiseEvent()
{
RuleRecognizedEvent();
}
}



My C# COM IDispatch interface (RuleRecognizedEvents.cs)
-------------------------------------------------------
namespace SAPITest.SpeechRecognitionEngine.SAPI
{
[GuidAttribute("E78BC57E-F44B-402a-87EA-89ED2D0E2ED0"), InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface RuleRecognizedEvents
{
[DispId(1)]
void RuleRecognized();
}
}



My VC++ class that implements the server's IDispatch interface
--------------------------------------------------------------
class ATL_NO_VTABLE RuleRecognizedEventHandler :
public IDispEventSimpleImpl<0, RuleRecognizedEventHandler, &DIID_RuleRecognizedEvents>
{
public:

BEGIN_SINK_MAP(RuleRecognizedEventHandler)
SINK_ENTRY_EX(0, DIID_RuleRecognizedEvents, 1, OnRuleRecognized)
END_SINK_MAP()


HRESULT __stdcall OnRuleRecognized()
{
OutputDebugString("Event Raised!");

return S_OK;
}

};



Code snippet from the VC++ function where I attempt to call DispEventAdvise
---------------------------------------------------------------------------

CComPtr<ISAPISpeechRecognitionEngine> sapiSRE;
hr = CoCreateInstance( CLSID_SAPISpeechRecognitionEngine,
NULL,
CLSCTX_INPROC_SERVER,
IID_ISAPISpeechRecognitionEngine,
(void **)&sapiSRE);

RuleRecognizedEventHandler* eventHandler = new RuleRecognizedEventHandler();

hr = eventHandler->DispEventAdvise(sapiSRE);
^^^^^^^^^^^^^^^^^^^^^^^
This is where the error occurs. hr comes back as CONNECT_E_NOCONNECTION.



The TLH file generated for my DLL
---------------------------------

#pragma once
#pragma pack(push, 8)

#include <comdef.h>

//
// Forward references and typedefs
//

struct __declspec(uuid("55f1525a-e94b-4ed0-a77a-2f7473d105f8"))
/* LIBID */ __SAPITest;
struct __declspec(uuid("e78bc57e-f44b-402a-87ea-89ed2d0e2ed0"))
/* dispinterface */ RuleRecognizedEvents;
struct __declspec(uuid("a94bc2e9-988c-3f0f-a862-1297e3bc1ff8"))
/* dual interface */ ISAPISpeechRecognitionEngine;
struct /* coclass */ RuleRecognizedDelegate;
struct /* coclass */ SAPISpeechRecognitionEngine;
struct __declspec(uuid("d9de3c02-7d25-369f-992e-8752d781568e"))
/* dual interface */ _RuleRecognizedDelegate;

//
// Smart pointer typedef declarations
//

_COM_SMARTPTR_TYPEDEF(RuleRecognizedEvents, __uuidof(RuleRecognizedEvents));
_COM_SMARTPTR_TYPEDEF(ISAPISpeechRecognitionEngine, __uuidof(ISAPISpeechRecognitionEngine));
_COM_SMARTPTR_TYPEDEF(_RuleRecognizedDelegate, __uuidof(_RuleRecognizedDelegate));

//
// Type library items
//

struct __declspec(uuid("e78bc57e-f44b-402a-87ea-89ed2d0e2ed0"))
RuleRecognizedEvents : IDispatch
{};

struct __declspec(uuid("a94bc2e9-988c-3f0f-a862-1297e3bc1ff8"))
ISAPISpeechRecognitionEngine : IDispatch
{
//
// Raw methods provided by interface
//

virtual HRESULT __stdcall Initialize (
/*[in]*/ BSTR grammarXmlString ) = 0;
virtual HRESULT __stdcall startListening ( ) = 0;
virtual HRESULT __stdcall stopListening ( ) = 0;
virtual HRESULT __stdcall test (
/*[out,retval]*/ BSTR * pRetVal ) = 0;
};

struct __declspec(uuid("4ae3bafe-ae1c-3d97-8608-31fa3eb2d598"))
RuleRecognizedDelegate;
// [ default ] interface _RuleRecognizedDelegate
// interface _Delegate
// interface _Object
// interface ICloneable
// interface ISerializable

struct __declspec(uuid("dcfb16e7-7da3-4f72-8f9f-9378d2620c48"))
SAPISpeechRecognitionEngine;
// interface _Object
// [ default ] interface ISAPISpeechRecognitionEngine
// [ default, source ] dispinterface RuleRecognizedEvents

struct __declspec(uuid("d9de3c02-7d25-369f-992e-8752d781568e"))
_RuleRecognizedDelegate : IDispatch
{};

//
// Named GUID constants initializations
//

extern "C" const GUID __declspec(selectany) LIBID_SAPITest =
{0x55f1525a,0xe94b,0x4ed0,{0xa7,0x7a,0x2f,0x74,0x73,0xd1,0x05,0xf8}};
extern "C" const GUID __declspec(selectany) DIID_RuleRecognizedEvents =
{0xe78bc57e,0xf44b,0x402a,{0x87,0xea,0x89,0xed,0x2d,0x0e,0x2e,0xd0}};
extern "C" const GUID __declspec(selectany) IID_ISAPISpeechRecognitionEngine =
{0xa94bc2e9,0x988c,0x3f0f,{0xa8,0x62,0x12,0x97,0xe3,0xbc,0x1f,0xf8}};
extern "C" const GUID __declspec(selectany) CLSID_RuleRecognizedDelegate =
{0x4ae3bafe,0xae1c,0x3d97,{0x86,0x08,0x31,0xfa,0x3e,0xb2,0xd5,0x98}};
extern "C" const GUID __declspec(selectany) CLSID_SAPISpeechRecognitionEngine =
{0xdcfb16e7,0x7da3,0x4f72,{0x8f,0x9f,0x93,0x78,0xd2,0x62,0x0c,0x48}};
extern "C" const GUID __declspec(selectany) IID__RuleRecognizedDelegate =
{0xd9de3c02,0x7d25,0x369f,{0x99,0x2e,0x87,0x52,0xd7,0x81,0x56,0x8e}};

#pragma pack(pop)



My only idea as to why this doesn't work is that the event signature for RuleRecognized() doesn't exist in the TLH file anywhere. I would assume that it should be in
struct __declspec(uuid("e78bc57e-f44b-402a-87ea-89ed2d0e2ed0"))
RuleRecognizedEvents : IDispatch
{};
but, I'm not sure.


Any help you could give me would greatly be appreciated, as I need to be able to perform DispEventAdvise on my event handler successfully.
I appologize for all the code, but I think that's the only real way to explain what is going on.

Thank you!