动态创建COM可见界面

时间:2014-08-08 12:33:37

标签: c# com dispatch

对不起,如果这是一个糟糕的标题。 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中,因为这会使我的代码库更小更容易管理(因为它变得相当大)

所以我怎样才能实现我追求的目标?

0 个答案:

没有答案