服务器端编程之如何开发IDispatch接口的实现类

首先需要决定的是是否使用type infomation?

那些简化IDispatch实现的helper method需要使用类型信息。

IDispatch接口的四个方法从客户端的角度来看是关联的。

      1. IDispatch::GetTypeInfoCount

            IDispatch::GetTypeInfoCount function is called by the client to determine whether type information is available for the object.

            如果有类型信息,则实现类在初始化时需要获取IDispatch子接口的类型信息以便后续方法使用。

     2. IDispatch::GetTypeInfo

         获取IDispatch子接口的类型信息。

     3. IDispatch::GetIDsOfNames

         实现IDispatch的子接口可能有多个方法,此方法即根据输入的method name及其参数名得到DISPID以便调用Invoke方法。

      4. IDispatch::Invoke

         第一个参数就是上面得到的DISPID,代表要调用哪个方法。第五个参数是一个DISPPARAMS结构体数组,包含相应的参数信息。

如果client端通过调用GetIDsOfNames获取dispid然后再调用invoke则称为late binding。如果通过type library获取dispid缓存以便使用则成为early binding。

由于IDispatch自动化接口不容易使用,微软推荐采用dual interface, 即面向不同的客户端,如果client采用VB Script则通过自动化接口访问,如果client端采用C++则使用custom interface即COM技术。

DISPPARAMS:   

typedef struct tagDISPPARAMS {
    // Array of arguments
    [size_is(cArgs)] VARIANTARG* rgvarg;
    // Array of DISPIDs of named arguments
    [size_is(cNamedArgs)] DISPID* rgdispidNamedArgs;

    // Total number of arguments
    UINT cArgs;

    // Number of named arguments
    UINT cNamedArgs;
} DISPPARAMS;

理解position arguments VS named arguments

首先理解

1) Parameters are automatically assigned a DISPID value based on their position within the argument list. For example, the Sum method has three parameters that are implicitly assigned DISPIDs as follows:

HRESULT Sum([optional, defaultvalue(-1)] int x, // DISPID = 0
            [optional, defaultvalue(-1)] int y, // DISPID = 1
            [out, retval] int* retvalue);       // DISPID = 2

2) 参数数组rgvarg是按照相反的顺序来存储参数的。so that rgvarg[0] contains the last argument and rgvarg[cArgs _ 1] contains the first argument。

以named arguments为例来说明DISPPARAMS的设置。

To omit an optional parameter when you use named arguments, you just don't pass it.

VARIANTARG SumArg;
VariantInit(&SumArg);
SumArg.vt = VT_I4;
SumArg.lVal = 5;
//用DispId=1来表明上面设置的参数5是针对y的。
DISPID DispId = 1; // The y parameter

DISPPARAMS Params = { &SumArg, &DispId, 1, 1 };

// Now IDispatch::Invoke calls ISum::Sum(-1, 5)

Building Automation Clients in C++

     1. Initializing COM (CoInitializeEx)

     2. Instantiating a class (CoCreateInstance)

     3. 调用QueryInterface获取IDispatch的实现类

     4. 如果第三步成功则调用IDispatch::GetIDsOfNames获取DISPID

     5. 调用invoke

         此方法最困难的部分就是准备包含方法参数的DISPPARAMS结构体。

         这里需要注意的是参数是按照从右到左的顺序存储在dispparams结构体中的数组中的。

        namedarguments & positionarguments两种方式构建DISPPARAMS。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值