delphi - How to Consume COM Server (ATL, DLL Surrogate) in .NET C# WinService? -


i have dll com server, used 1 old delphi exe-application.

com server written many years ago (not me) in c++ atl. implements callbacks (event - same?) - using outgoing interface iconnectionpointimpl. class factory singleton (marked declare_classfactory_singleton)

now required com server have shared between more 1 clients: both delphi , c# (.net 2.0, vs2008). put dllsurrogate , can use multiple delphi clients, using class inherited toleserver, overriding getserver method use cocreateinstance (because getactiveobject fails) , it's working.

now need consume c# winservice , don't know start. wrote little c# hello-world use winapi cocreateinstance , dllimport("ole32.dll") - able connect existing instance com server cannot subscribe events.

here dll meta-data imported vs: enter image description here

i don't know if correct way. here 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 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 don't know further                     lievev.featureabouttoexpire += aboutexpirehandler;                 }             }             catch (exception e)             {                 console.writeline(e.message);                 throw;             }              console.readline();         }     } } 

any advices, links , know-hows welcome.

it seems succeeded connect to- , handle events of dll (in-proc) com server.

  1. i put com server dll surrogate (howto here).
  2. delphi client side - form com wrapper class, inheriting toleserver class overridden getserver method:

function tswmgr.getserver: iunknown; begin olecheck(cocreateinstance(serverdata^.classid, nil, clsctx_local_server, iunknown, result)); end;

  1. c# (hello-world client) side (after consulting howtos this):

//using swlmlib; //using system.runtime.interopservices; //using system.runtime.interopservices.comtypes;

[flags] enum returncode : uint {     s_ok = 0, s_false = 1, regdb_e_classnotreg = 0x80040154, class_e_noaggregation = 0x80040110, e_nointerface = 0x80004002, e_pointer = 0x80004003 }  [flags] enum clsctx : uint {     clsctx_inproc_server = 0x1, clsctx_inproc_handler = 0x2, clsctx_local_server = 0x4,     //... //others     clsctx_all = clsctx_server | clsctx_inproc_handler }  /// <summary> /// sink class implementig com server outgoing interface swlmlib.iswmgrevents  /// </summary> [classinterface(classinterfacetype.none)] class mysink : swlmlib.iswmgrevents {     public void featureabouttoexpire(swlmlib.ifeature pfeature, int hoursremained)     {         console.writeline("{0} featureabouttoexpire: feature {1} hours={2}", datetime.now, pfeature.code, hoursremained);         marshal.releasecomobject(pfeature); //wtf??? without line com server object not released!     }      public void featureexpired(swlmlib.ifeature pfeature)     {         console.writeline("featureexpired: feature {0}", pfeature.code);         marshal.releasecomobject(pfeature); //without line com server object not released!     } }  class program {     //import "cocreateinstance" play run context of created com-object (3rd parameter)     [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);      static void main(string[] args)     {         try         {             guid swmgrclassobjectguid = typeof(swlmlib.swmgrclass).guid;    //{8eaafad7-73f8-403b-a53b-4400e16d8edf}             guid iunknownguid = new guid("00000000-0000-0000-c000-000000000046"); //can written in more pretty style?              swlmlib.iswmgr lintfswlmgr = null;              /* create in-proc server because, seems cocreateinstance invoked clsctx_inproc_server flag settled             type type = type.gettypefromclsid(swmgrclassobjectguid), true);             object instance0 = activator.createinstance(type);             lintfswlmgr = (instance0 swlmlib.iswmgr); */              guid ev1 = typeof(iswmgrevents).guid;             object instance = null;              unsafe             {                 uint32 dwres = cocreateinstance(swmgrclassobjectguid,                                                 intptr.zero,                                                 (uint)(clsctx.clsctx_local_server), //if or clsctx_inproc_server inproc server created, because of dll com server                                                 iunknownguid,                                                 out instance);                 if (dwres != 0)                 {                     int ierror = marshal.getlastwin32error();                     console.writeline("cocreateinstance error = {0}, lastwin32error = {1}", dwres, ierror);                     return;                 }                 lintfswlmgr = (instance swlmlib.iswmgr);             }              if (lintfswlmgr != null)             {                 //lintfswlmgr.initializemethod(...); //initialize object                  //find connection point events                 guid iswmgreventsguid = typeof(swlmlib.iswmgrevents).guid;      //{c13a9d38-4bb0-465b-bf4a-487f371a5538} interface evenets handling                 iconnectionpoint lcp = null;                 iconnectionpointcontainer lcpc = (instance iconnectionpointcontainer);                 lcpc.findconnectionpoint(ref iswmgreventsguid, out lcp);                  mysink lsink = new mysink();                 int32 dweventscookie;                 lcp.advise(lsink, out dweventscookie);                 console.writeline("waiting events handling...");                 console.writeline("press enter exit...");                  console.readline(); // until eneter not hit, events arrive                 //here starting unsubscribe events , com objects cleanup                 lcp.unadvise(dweventscookie);                 marshal.releasecomobject(lcp);                  marshal.releasecomobject(lintfswlmgr);              }          }         catch (exception e)         {             console.writeline(e.message);             throw;         }     } } 

maybe not best way (like tblimp.exe , or com wrappers) raw way works.


Comments

Popular posts from this blog

monitor web browser programmatically in Android? -

Shrink a YouTube video to responsive width -

wpf - PdfWriter.GetInstance throws System.NullReferenceException -