私は DLL Com サーバーを持っていますが、実際には 1 つの古い Delphi exe アプリケーションでしか使用されていません。
COM サーバーは (私ではなく) 何年も前に C++ ATL で作成されました。コールバックを実装します (イベント - 同じですか?) - 発信インターフェイスを使用しますIConnectionPointImpl
。Class Factory はシングルトン ( でマークDECLARE_CLASSFACTORY_SINGLETON
)
現在、この COM サーバーを複数のクライアント (Delphi と C# (.NET 2.0、VS2008) の両方) で共有する必要があります。私はそれを入れてDllSurrogate
、複数のDelphiクライアントから継承されたクラスを使用して、常に使用するメソッドをTOleServer
オーバーライドして(通常は失敗するため)、それを使用できるようになりました。GetServer
CoCreateInstance
GetActiveObject
ここで、C# WinService からそれを使用する必要がありますが、どこから始めればよいかわかりません。WinApi を使用する小さな C# Hello-world を作成CoCreateInstance
しDllImport("ole32.dll")
ました。COM サーバーから既存のインスタンスに接続できますが、イベントをサブスクライブできません。
VS によってインポートされた DLL META-DATA は次のとおりです。
これが正しい方法かどうかはわかりません。近似コードは次のとおりです。
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();
}
}
}
アドバイス、リンク、ノウハウは大歓迎です。