对不起,如果这是一个糟糕的标题。 OPOS使用双调度COM接口在服务对象和控制对象之间传递事件。在我正在制作的库中,我有2个基本的OPOS服务对象。一个是MSR,另一个是Pinpad。当OPOS使用OpenService时,第3个参数是一个对象(它实际上只是双分派COM接口的一个实例)。
仅供参考,这是MSR界面
[ComImport, Guid("CCB91121-B81E-11D2-AB74-0040054C3719"), InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface COPOSMSR : Base.COPOS
{
[Description("method SOData")]
void SOData([In] int Status);
[Description("method SODirectIO")]
void SODirectIO([In] int EventNumber, [In, Out] ref int pData, [In, Out, MarshalAs(UnmanagedType.BStr)]ref string pString);
[Description("method SOError")]
void SOError([In] int ResultCode, [In] int ResultCodeExtended, [In] int ErrorLocus, [In, Out] ref int pErrorResponse);
[Description("method SOOutputComplete")]
void SOOutputComplete([In] int OutputID);
[Description("method SOStatusUpdate")]
void SOStatusUpdate([In] int Data);
[Description("method SOProcessID")]
void SOProcessID([Out] out int pProcessID);
}
这是pinpad界面
[ComImport, Guid("CCB91131-B81E-11D2-AB74-0040054C3719"), InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface COPOSPINPAD : Base.COPOS
{
[Description("method SOData")]
void SOData([In] int Status);
[Description("method SODirectIO")]
void SODirectIO([In] int EventNumber, [In, Out] ref int pData, [In, Out, MarshalAs(UnmanagedType.BStr)]ref string pString);
[Description("method SOError")]
void SOError([In] int ResultCode, [In] int ResultCodeExtended, [In] int ErrorLocus, [In, Out] ref int pErrorResponse);
[Description("method SOOutputComplete")]
void SOOutputComplete([In] int OutputID);
[Description("method SOStatusUpdate")]
void SOStatusUpdate([In] int Data);
[Description("method SOProcessID")]
void SOProcessID([Out] out int pProcessID);
}
你可以看到2几乎是相同的(就界面而言它们是相同的)它们只在Guid中有所不同。所以我认为嘿,我知道..如何将这些双胞胎方法移动到COPOS界面并使其成为DualDispatch ......无法编译。那么我想,好吧我如何通过使用CLSID来创建接口,因为我知道它们是什么。但我无法弄清楚如何使用激活器设置一个对象(我相信我需要这样做)
现在来说明为什么它如此重要。我有一个OPOSBase抽象类,除其他外,负责触发事件。所有设备的射击事件都是相同的概念。我开始只使用一台设备,一台MSR设备。当我添加对pinpad设备的支持时,我决定将所有常见属性,方法和事件移动到所述OPOSBase类,如第1章中UPOS规范中所述。所以现在我有了这个
[ComImport, Guid("CCB91131-B81E-11D2-AB74-0040054C3719"), InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface COPOSPINPAD : Base.COPOS
{
}
[ComImport, Guid("CCB91121-B81E-11D2-AB74-0040054C3719"), InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface COPOSMSR : Base.COPOS
{
}
public interface COPOS
{
[Description("method SOData")]
void SOData([In] int Status);
[Description("method SODirectIO")]
void SODirectIO([In] int EventNumber, [In, Out] ref int pData, [In, Out, MarshalAs(UnmanagedType.BStr)]ref string pString);
[Description("method SOError")]
void SOError([In] int ResultCode, [In] int ResultCodeExtended, [In] int ErrorLocus, [In, Out] ref int pErrorResponse);
[Description("method SOOutputComplete")]
void SOOutputComplete([In] int OutputID);
[Description("method SOStatusUpdate")]
void SOStatusUpdate([In] int Data);
[Description("method SOProcessID")]
void SOProcessID([Out] out int pProcessID);
}
在我的OPOSBase中,我有一个名为controlObject的受保护字段COPOS
。 OPOSBase有一个名为SetControlObject(object dispatchObject)
的抽象方法,在MSRBase中,我执行此操作this.controlObject = (COPOSMSR)dispatchObject
,同样在PinpadBase中执行此操作this.controlObject = (COPOSPinpad)dispatchObject
这让我把所有“Fire___Event”方法放入OPOSBase中。然后开火说一个数据事件就像这样
public virtual void FireDataEvent(OPOSDataEvent oposEvent)
{
lock (methodLocker)
{
PreFireDataEvent(oposEvent);
logger.TraceStart();
oposEvent.LoadInputProperties(this);
this.DataEventEnabled = false;
controlObject.SOData(oposEvent.Status);
logger.TraceEnd();
PostFireDataEvent(oposEvent);
}
}
然而,使用上面列出的代码,它会在controlObject.SOData(oposEvent.Status);
上爆炸(抱歉没有错误,但它与GUID有关)。作为测试,我将GUID和接口类型移动到COPOS,现在我的DataEvent再次工作。我真的非常希望能够将火灾事件保存在OPOSBase中,因为这会使我的代码库更小更容易管理(因为它变得相当大)
所以我怎样才能实现我追求的目标?