MEYWDの答えをさらに進めるために、C#での基本的なインターフェイスの外観を投稿したいと思います。
[ComVisible(true), Guid("Put a GUID here")]
public interface IMSR
{
//Common Opos
[DispId(0x01)]
int CheckHealth([In] int lLevel);
[DispId(0x02)]
int ClaimDevice([In] int lTimeOut);
[DispId(0x03)]
int ClearInput();
[DispId(0x04)]
int ClearInputProperties();
[DispId(0x05)]
int ClearOutput();
[DispId(0x06)]
int CloseService();
[DispId(0x07)]
int COFreezeEvents([In, MarshalAs(UnmanagedType.VariantBool)] bool Freeze);
[DispId(0x08)]
int CompareFirmwareVersion([In, MarshalAs(UnmanagedType.BStr)] string FirmwareFileName, [In, Out]ref int pResult);
[DispId(0x09)]
int DirectIO([In] int lCommand, [In, Out] ref int pData, [In, Out, MarshalAs(UnmanagedType.BStr)] ref string pString);
[DispId(0x0A)]
int OpenService([In, MarshalAs(UnmanagedType.BStr)] string lpclDevClass, [In, MarshalAs(UnmanagedType.BStr)] string lpclDevName, [In, MarshalAs(UnmanagedType.IDispatch)] object lpDispatch);
[DispId(0x0B)]
int ReleaseDevice();
[DispId(0x0C)]
int ResetStatistics([In, MarshalAs(UnmanagedType.BStr)] string StatisticsBuffer);
[DispId(0x0D)]
int RetrieveStatistics([In, Out, MarshalAs(UnmanagedType.BStr)] ref string pStatisticsBuffer);
[DispId(0x0E)]
int UpdateFirmware([In, MarshalAs(UnmanagedType.BStr)] string FirmwareFileName);
[DispId(0x0F)]
int UpdateStatistics([In, MarshalAs(UnmanagedType.BStr)] string StatisticsBuffer);
[DispId(0x10)]
int GetPropertyNumber([In] int lPropIndex);
[DispId(0x11)]
string GetPropertyString([In] int lPropIndex);
[DispId(0x12)]
void SetPropertyNumber([In] int lPropIndex, [In] int nNewValue);
[DispId(0x13)]
void SetPropertyString([In] int lPropIndex, [In, MarshalAs(UnmanagedType.BStr)] string StringData);
//MSR Specific
[DispId(0x14)]
int AuthenticateDevice([In, MarshalAs(UnmanagedType.BStr)] string deviceResponse);
[DispId(0x15)]
int DeauthenticateDevice([In, MarshalAs(UnmanagedType.BStr)] string deviceResponse);
[DispId(0x16)]
int RetrieveCardProperty([In, MarshalAs(UnmanagedType.BStr)] string propertyName, [Out, MarshalAs(UnmanagedType.BStr)] out string cardProperty);
[DispId(0x17)]
int RetrieveDeviceAuthenticationData([In, Out, MarshalAs(UnmanagedType.BStr)] ref string challenge);
[DispId(0x18)]
int UpdateKey([In, MarshalAs(UnmanagedType.BStr)]string key,[In, MarshalAs(UnmanagedType.BStr)] string keyName);
[DispId(0x19)]
int WriteTracks([In] object data,[In] int timeout);
}
これはMSRの場合ですが、CommonOPOSメソッドはすべてのタイプのデバイスで同じです。したがって、変更する必要があるのは、DispID 0x14(20)以降だけです。私が行ったことは、OPOSドキュメントと比較して、彼らが付けた署名をC#に変換することでした。私はこの方法で約6つのSOを作成しましたが、さまざまなシナリオですべてが正常に機能しています。
もう1つの注意点は、OpenServiceメソッドにあります。最後の引数がオブジェクトであることがわかります。これがControlオブジェクトのインスタンスです。あなたがする必要があるのはあなたのためにCOMオブジェクトを公開するあなたのプロジェクトで別のインターフェースを作ることです。私のMSRの例に固執するために、ここにあなたが置くものがあります。
[ComImport, Guid("CCB91121-B81E-11D2-AB74-0040054C3719"), InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface COPOSMSR
{
void SOData([In] int Status);
void SODirectIO([In] int EventNumber, [In, Out] ref int pData, [In, Out, MarshalAs(UnmanagedType.BStr)] ref string pStrIng);
void SOError([In] int ResultCode, [In] int ResultCodeExtended, [In] int ErrorLocus, [In, Out] ref int pErrorResponse);
void SOOutputCompleteDummy([In] int OutputID);
void SOStatusUpdate([In] int Data);
void SOProcessID([Out] out int pProcessID);
}
私はOPOSのソースコードの署名です。ソースコードを検索すると、次のような小さなコメントが表示されます。(msr OPOSソースコードから)これは、イベントを発生させるために何を実装するかを知っているためです。
c:\ Program Files(x86)\ Opos \ oposSrc \ zMSR \ MSR.idl
[
object,
uuid(CCB91121-B81E-11D2-AB74-0040054C3719),
dual,
helpstring("IOPOSMSR 1.5 Interface"),
pointer_default(unique)
]
interface IOPOSMSR_1_5 : IDispatch
{
// Methods for use only by the Service Object
[id(1), hidden, helpstring("method SOData")] HRESULT SOData( [in] long Status );
[id(2), hidden, helpstring("method SODirectIO")] HRESULT SODirectIO( [in] long EventNumber, [in, out] long* pData, [in, out] BSTR* pString );
[id(3), hidden, helpstring("method SOError")] HRESULT SOError( [in] long ResultCode, [in] long ResultCodeExtended, [in] long ErrorLocus, [in, out] long* pErrorResponse );
[id(4), hidden, helpstring("method SOOutputCompleteDummy")] HRESULT SOOutputCompleteDummy( [in] long OutputID );
[id(5), hidden, helpstring("method SOStatusUpdate")] HRESULT SOStatusUpdate( [in] long Data );
[id(9), hidden, helpstring("method SOProcessID")] HRESULT SOProcessID( [out, retval] long* pProcessID );
これらの2つの基本的なものを使用すると、SOを作成できます。イベントを発生させるのも非常に簡単です。これが私がテストとしてそれをした方法です
public int OpenService(string lpclDevClass, string lpclDevName, object lpDispatch)
{
controlObject = (COPOSMSR)lpDispatch;
controlObject.SOData(1)//I just fired a Data Event
}
C ++でSOを構築するのは、C#よりも難しいというのも私の経験です。C#が非常に単純にするステップは他にもたくさんあります。
私が始めるのに十分な情報であったいくつかの良い読み物。
COM相互運用パート1:C#クライアントチュートリアル
http://msdn.microsoft.com/en-us/library/aa645736(v=vs.71).aspx
COM相互運用パート2:C#サーバーチュートリアル
http://msdn.microsoft.com/en-us/library/aa645738(v=vs.71).aspx
COMデータ型
https://msdn.microsoft.com/en-us/library/sak564ww%28v=vs.100%29.aspx