1. This project demonstrates the problems of passing a referenced SAFEARRAY as a parameter to a dispinterface-based event from an unmanaged COM server to a managed event handler.
2. This project is divided into 3 Visual Studio Projects :
- An unmanaged COM server which fires events.
- A managed C# client app which handles the events using the standard delegate method.
- A managed C# client app which handles the events using the ICustomQueryInterface method.
3. The UnmanagedCOMServer folder contains TestCOMServer which is an unmanaged COM server project written in ATL.
3.1 Its IDL defines an interface ITestCOMClass which is implemented by the CTestCOMServer class.
3.2 There is also a dispinterface-based event interface named _ITestCOMClassEvents.
3.3 Each method of ITestCOMClass fires an event from _ITestCOMClassEvents. For example, TestMethod01 fires Event01(), TestMethod02 fires Event02(), etc.
3.4 Each event demonstrates the use of different referenced types as parameters in event firing.
3.5 For example :
- Event01() demonstrates the use of a referenced SAFEARRAY.
- Event02() demonstrates the use of a referenced VARIANT.
- Event03() demonstrates the use of a referenced VARIANT_BOOL.
- Event04() demonstrates the use of a referenced BSTR.
4. The ManagedClients folder contains ConsoleClient01 which references TestCOMServer.
4.1 It is a Console-based application. It demonstrates the cited problems with event handling in managed code.
4.2 There are 4 main static methods DoTest1(), DoTest2(), DoTest3() and DoTest4().
4.3 Each DoTestx() method demonstrates the calling of one method of ITestCOMClass and the hooking up to an associated event.
4.4 Of these, only the managed event handler for Event03() works correctly.
4.5 All the others present some problem or another as indicated in the comments.
5. The ManagedClients folder also contains ConsoleClient02 which references TestCOMServer.
5.1 It contains the workaround code for the cited problem.
5.2 The workarounds involve the use of COM's native IConnectionPoint and IConnectionPointContainer to do the event hookup.
5.3 Two techniques are used for event handling :
- Defining an event handling class that implements the event interface itself (i.e. the _ITestCOMClassEvents interface).
- Defining an event handling class that implements the COM IDispatch interface as well as the ICustomQueryInterface interface.
5.4 The first technique is demonstrated by the TestCOMClassEventsListener class.
5.5 The second technique is demonstrated by the TestCOMClassEventsListener2 class.
5.6 In my code, I show that the use of the IDispatch interface implementation as facilitated by ICustomQueryInterface is a much better solution.
6. All projects were created using Microsoft Visual Studio Community 2015 version 14.0.23107.0 D14REL.
7. For more documentation, please refer to the following links :
Passing a Reference to a SAFEARRAY as Parameter to a Managed COM Event Handler Part 1.
Passing a Reference to a SAFEARRAY as Parameter to a Managed COM Event Handler Part 2.
Passing a Reference to a SAFEARRAY as Parameter to a Managed COM Event Handler Part 3.