How to pass SAFEARRAY to COM object through IDispatch?

前端 未结 1 1397
渐次进展
渐次进展 2020-12-17 01:24

i am trying to call a method of COM object, where one of the documented parameters is an \"array of bytes\". The actual declartion depends

1条回答
  •  隐瞒了意图╮
    2020-12-17 01:40

    This should give you some insight:

    On the caller side, C# code:

    Foo foo = new Foo();
    byte[] input = new byte[] { 1, 2, 3, 4 };
    byte[] output = foo.Bar(input);
    byte[] referenceOutput = new byte[] { 4, 3, 2, 1 };
    Debug.Assert(Enumerable.SequenceEqual(output, referenceOutput));
    

    The Foo.Bar IDL:

    interface IFoo : IDispatch
    {
        [id(1)] HRESULT Bar([in] VARIANT vInput, [out, retval] VARIANT* pvOutput);
    };
    

    And C++ (ATL) server implementation with safe arrays:

    // IFoo
        STDMETHOD(Bar)(VARIANT vInput, VARIANT* pvOutput) throw()
        {
            _ATLTRY
            {
                ATLENSURE_THROW(vInput.vt == (VT_ARRAY | VT_UI1), E_INVALIDARG);
                CComSafeArray pInputArray(vInput.parray);
                ATLASSERT(pInputArray.GetDimensions() == 1);
                const ULONG nCount = pInputArray.GetCount();
                CComSafeArray pOutputArray;
                ATLENSURE_SUCCEEDED(pOutputArray.Create(nCount));
                for(ULONG nIndex = 0; nIndex < nCount; nIndex++)
                    pOutputArray[(INT) nIndex] = pInputArray[(INT) ((nCount - 1) - nIndex)];
                ATLASSERT(pvOutput);
                VariantInit(pvOutput);
                CComVariant vOutput(pOutputArray.Detach());
                ATLVERIFY(SUCCEEDED(vOutput.Detach(pvOutput)));
            }
            _ATLCATCH(Exception)
            {
                return Exception;
            }
            return S_OK;
        }
    

    Source: Trac, Subversion - beware Visual Studio 2012.

    0 讨论(0)
提交回复
热议问题