VT_BYREF

前言

如果使用变体类型的出参,必须指定VT_BYREF和数据类型的或

typedef struct FARSTRUCT tagVARIANT VARIANT;
typedef struct FARSTRUCT tagVARIANT VARIANTARG;

typedef struct tagVARIANT  {
   VARTYPE vt;
   unsigned short wReserved1;
   unsigned short wReserved2;
   unsigned short wReserved3;
   union {
      Byte                    bVal;                 // VT_UI1.
      Short                   iVal;                 // VT_I2.
      long                    lVal;                 // VT_I4.
      float                   fltVal;               // VT_R4.
      double                  dblVal;               // VT_R8.
      VARIANT_BOOL            boolVal;              // VT_BOOL.
      SCODE                   scode;                // VT_ERROR.
      CY                      cyVal;                // VT_CY.
      DATE                    date;                 // VT_DATE.
      BSTR                    bstrVal;              // VT_BSTR.
      DECIMAL                 FAR* pdecVal          // VT_BYREF|VT_DECIMAL.
      IUnknown                FAR* punkVal;         // VT_UNKNOWN.
      IDispatch               FAR* pdispVal;        // VT_DISPATCH.
      SAFEARRAY               FAR* parray;          // VT_ARRAY|*.
      Byte                    FAR* pbVal;           // VT_BYREF|VT_UI1.
      short                   FAR* piVal;           // VT_BYREF|VT_I2.
      long                    FAR* plVal;           // VT_BYREF|VT_I4.
      float                   FAR* pfltVal;         // VT_BYREF|VT_R4.
      double                  FAR* pdblVal;         // VT_BYREF|VT_R8.
      VARIANT_BOOL            FAR* pboolVal;        // VT_BYREF|VT_BOOL.
      SCODE                   FAR* pscode;          // VT_BYREF|VT_ERROR.
      CY                      FAR* pcyVal;          // VT_BYREF|VT_CY.
      DATE                    FAR* pdate;           // VT_BYREF|VT_DATE.
      BSTR                    FAR* pbstrVal;        // VT_BYREF|VT_BSTR.
      IUnknown                FAR* FAR* ppunkVal;   // VT_BYREF|VT_UNKNOWN.
      IDispatch               FAR* FAR* ppdispVal;  // VT_BYREF|VT_DISPATCH.
      SAFEARRAY               FAR* FAR* pparray;    // VT_ARRAY|*.
      VARIANT                 FAR* pvarVal;         // VT_BYREF|VT_VARIANT.
      void                    FAR* byref;           // Generic ByRef.
      char                    cVal;                 // VT_I1.
      unsigned short          uiVal;                // VT_UI2.
      unsigned long           ulVal;                // VT_UI4.
      int                     intVal;               // VT_INT.
      unsigned int            uintVal;              // VT_UINT.
      char FAR *              pcVal;                // VT_BYREF|VT_I1.
      unsigned short FAR *    puiVal;               // VT_BYREF|VT_UI2.
      unsigned long FAR *     pulVal;               // VT_BYREF|VT_UI4.
      int FAR *               pintVal;              // VT_BYREF|VT_INT.
      unsigned int FAR *      puintVal;             //VT_BYREF|VT_UINT.
   };
};

例子

void fnTest2() {
    HRESULT hr = S_FALSE;
    LONG lRc = 0;
    CLSID clsid;
    BSTR bstrStr = NULL;
    IUnknown* pUnk = NULL;
    IDispatch* pDispatch = NULL;
    OLECHAR* szFunction = NULL;
    DISPID dispid;
    DISPPARAMS dispparams = {NULL, NULL, 0, 0};
    VARIANT var[10];
    VARIANT varRc[10];
    LONG lVal[10] = {0};

    do {
        hr = CLSIDFromProgID(OLESTR("MyStringComDll.MyString.1"), &clsid);
        if (FAILED(hr)) {
            break;
        }

        hr = CoCreateInstance(CLSID_MyString, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void**)&pUnk);
        if (FAILED(hr)) {
            break;
        }

        hr = pUnk->QueryInterface(IID_IDispatch, (void**)&pDispatch);
        if (FAILED(hr)) {
            break;
        }

        szFunction = OLESTR("test");
        /// 出参 dispid 为虚表中length函数对应的索引项
        hr = pDispatch->GetIDsOfNames(IID_NULL, &szFunction, 1, LOCALE_USER_DEFAULT, &dispid);
        if (FAILED(hr)) {
            break;
        }

        /// 使用出参的例子, 要使用VARIANT.pX, VARIANT.vt 必须是VT_BYREF | VT_数据类型
        var[0].vt = VT_BYREF | VT_I4;
        var[0].plVal = &lVal[1];

        var[1].vt = VT_BYREF | VT_I4;
        var[1].plVal = &lVal[0];

        dispparams.rgvarg = var;
        dispparams.rgdispidNamedArgs = NULL; 
        dispparams.cArgs = 2;
        dispparams.cNamedArgs = 0;

        hr = pDispatch->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT,
                       DISPATCH_METHOD, &dispparams, varRc, NULL, 
                       NULL);
        if (FAILED(hr)) {
            break;
        }

        wprintf(L"all ok\n");
    } while (0);

    if (NULL != pDispatch) {
        pDispatch->Release();
    }

    if (NULL != pUnk) {
        pUnk->Release();
    }
}

COM接口定义与实现

// MyStringComDll.idl : IDL source for MyStringComDll.dll
//

// This file will be processed by the MIDL tool to
// produce the type library (MyStringComDll.tlb) and marshalling code.

import "oaidl.idl";
import "ocidl.idl";
    [
        object,
        uuid(DEA21FB9-6309-4B7C-BA39-453685F6B081),
        dual,
        helpstring("IMyString Interface"),
        pointer_default(unique)
    ]
    interface IMyString : IDispatch
    {
        [id(1), helpstring("字符串赋值")] HRESULT assignment([in] LPOLESTR lpszSrc);
        [id(2), helpstring("字符串是否相等,靠出参返回")] HRESULT isEqual([in] LPOLESTR lpszSrc, [out]LONG* lplRc);
        [id(3), helpstring("字符串是否不相等")] HRESULT isNotEqual([in] LPOLESTR lpszSrc, [out]LONG* lplRc);

        [id(4), helpstring("字符串是否<入参字符串")] HRESULT isLessThan([in] LPOLESTR lpszSrc, [out]LONG* lplRc);
        [id(5), helpstring("字符串是否<=入参字符串")] HRESULT isLessThanOrEqual([in] LPOLESTR lpszSrc, [out]LONG* lplRc);

        [id(6), helpstring("字符串是否>入参字符串")] HRESULT isGreateThan([in] LPOLESTR lpszSrc, [out]LONG* lplRc);
        [id(7), helpstring("字符串是否>=入参字符串")] HRESULT isGreateThanOrEqual([in] LPOLESTR lpszSrc, [out]LONG* lplRc);

        [id(8), helpstring("字符串是为空")] HRESULT isEmpty([out]LONG* lplRc);
        [id(9), helpstring("附加一个字符串")] HRESULT Appends([in] LPOLESTR lpszSrc);

        [id(10), helpstring("求字符串长度")] HRESULT length([out]LONG* lplRc);
        [id(11), helpstring("得到字符串")] HRESULT GetString([out]BSTR* lpBstrStr);
        [id(12), helpstring("method test")] HRESULT test([out] long* lRc1, [out] long* lRc2 );
    };

[
    uuid(3F08DFAB-AF55-45DE-93D4-8120F9C67D44),
    version(1.0),
    helpstring("MyStringComDll 1.0 Type Library")
]
library MYSTRINGCOMDLLLib
{
    importlib("stdole32.tlb");
    importlib("stdole2.tlb");

    [
        uuid(26EF0212-1BF7-4E01-9988-37AD60087846),
        helpstring("MyString Class")
    ]
    coclass MyString
    {
        [default] interface IMyString;
    };
};
// MyString.h : Declaration of the CMyString

#ifndef __MYSTRING_H_
#define __MYSTRING_H_

#include "resource.h"       // main symbols
#include <comdef.h> ///< for _bstr_t

/////////////////////////////////////////////////////////////////////////////
// CMyString
class ATL_NO_VTABLE CMyString : 
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CMyString, &CLSID_MyString>,
    public IDispatchImpl<IMyString, &IID_IMyString, &LIBID_MYSTRINGCOMDLLLib>
{
public:
    CMyString()
    {
        m_bstrStr = OLESTR("");
    }

DECLARE_REGISTRY_RESOURCEID(IDR_MYSTRING)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CMyString)
    COM_INTERFACE_ENTRY(IMyString)
    COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()

// IMyString
public:
    STDMETHOD(test)(/*[out]*/ long* lRc1, /*[out]*/ long* lRc2 );
    STDMETHOD(isNotEqual)(/*[in]*/ LPOLESTR lpszSrc, /*[out]*/LONG* lplRc);
    STDMETHOD(assignment)(/*[in]*/  LPOLESTR lpszSrc);
    STDMETHOD(isEqual)(/*[in]*/  LPOLESTR lpszSrc, /*[out]*/ LONG* lplRc);

    STDMETHOD(isLessThan)(/*[in]*/  LPOLESTR lpszSrc, /*[out]*/ LONG* lplRc);
    STDMETHOD(isLessThanOrEqual)(/*[in]*/  LPOLESTR lpszSrc, /*[out]*/ LONG* lplRc);

    STDMETHOD(isGreateThan)(/*[in]*/  LPOLESTR lpszSrc, /*[out]*/ LONG* lplRc);
    STDMETHOD(isGreateThanOrEqual)(/*[in]*/  LPOLESTR lpszSrc, /*[out]*/ LONG* lplRc);

    STDMETHOD(isEmpty)(/*[out]*/ LONG* lplRc);
    STDMETHOD(Appends)(/*[in]*/  LPOLESTR lpszSrc);

    STDMETHOD(length)(/*[out]*/ LONG* lplRc);
    STDMETHOD(GetString)(/*[out]*/ BSTR* lpBstrStr);

    /// 私有成员变量
private:
    _bstr_t m_bstrStr; ///< 保存外面传来的字符串
};

#endif //__MYSTRING_H_
STDMETHODIMP CMyString::test(long *lRc1, long *lRc2)
{
    if ((NULL == lRc1) || (NULL == lRc2)) {
        return ERROR_INVALID_PARAMETER;
    }

    *lRc1 = 0x1111;
    *lRc2 = 0x2222;

    return S_OK; ///< invoke时,返回的hr并不是这里的返回值
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值