I have a DLL Com Server, actually used only by one old Delphi exe-application.
COM Server is written many years ago (not by me) in C++ ATL. It implements callbacks (event - is it the same?) - using outgoing interface IConnectionPointImpl. Class Factory is singleton (marked with DECLARE_CLASSFACTORY_SINGLETON)
Now it is required that this COM Server have to be shared between more than one clients: both Delphi and C# (.NET 2.0, VS2008). I put it as DllSurrogate and now I can use it from multiple Delphi clients, using class inherited from TOleServer, overriding GetServer method to use always CoCreateInstance (because GetActiveObject usually fails) and it's working.
Now I need to consume it from C# WinService and I don't know from where to start.
I wrote a little C# Hello-world which use WinApi CoCreateInstance and DllImport("ole32.dll") - I am able to connect to existing instance from COM Server but cannot subscribe to events.
Here is the DLL META-DATA imported by VS:

I don't know if this is correct way. Here is aproximative code:
using System;
using System.Collections.Generic;
using System.Text;
using SWLMLib;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
namespace TestSWLM
{
[Flags]
enum CLSCTX : uint
{
//... defines here CLSCTX
}
class Program
{
[DllImport("ole32.dll", EntryPoint = "CoCreateInstance", CallingConvention = CallingConvention.StdCall)]
static extern UInt32 CoCreateInstance([In, MarshalAs(UnmanagedType.LPStruct)] Guid rclsid,
IntPtr pUnkOuter, UInt32 dwClsContext, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid,
[MarshalAs(UnmanagedType.IUnknown)] out object rReturnedComObject);
public static void AboutExpireHandler(IFeature pFeature, int HoursRemained)
{
Console.WriteLine("AboutExpireHandler, pFeature = {0}", pFeature.Code);
}
static void Main(string[] args)
{
try
{
SWLMLib.ISWMgr lintfSWLMgr = null;
object instance = null;
UInt32 dwRes = CoCreateInstance(new Guid("8EAAFAD7-73F8-403B-A53B-4400E16D8EDF"), IntPtr.Zero, (uint)CLSCTX.CLSCTX_LOCAL_SERVER,
new Guid("00000000-0000-0000-C000-000000000046"), out instance);
SWLMLib.SWMgrClass lSWLMgr = null;
unsafe
{
lintfSWLMgr = (instance as SWLMLib.ISWMgr);
Type liType = instance.GetType();
}
if (lintfSWLMgr != null)
{
IntPtr iuknw = Marshal.GetIUnknownForObject(lintfSWLMgr);
IntPtr ipointer = IntPtr.Zero;
Guid lICPCGuid = typeof(IConnectionPointContainer).GUID;
Guid lICPGuid = typeof(IConnectionPoint).GUID;
Guid lIEv = new Guid("{C13A9D38-4BB0-465B-BF4A-487F371A5538}");
IConnectionPoint lCP = null;
IConnectionPointContainer lCPC = null;
Int32 r = Marshal.QueryInterface(iuknw, ref lICPCGuid, out ipointer);
lCPC = (IConnectionPointContainer)Marshal.GetObjectForIUnknown(ipointer);
lCPC.FindConnectionPoint(ref lIEv, out lCP);
Int32 outID;
lCP.Advise(???, out outID); // HERE I don't know what to do further
lIEvEv.FeatureAboutToExpire += AboutExpireHandler;
}
}
catch (Exception E)
{
Console.WriteLine(E.Message);
throw;
}
Console.ReadLine();
}
}
}
Any Advices, links and know-hows are welcome.