Информация об изменениях

Сообщение Получить SAFEARRAY через IDispatch::Invoke от 23.04.2020 2:30

Изменено 23.04.2020 3:07 _agg

Получить SAFEARRAY через IDispatch::Invoke
Есть вот такой метод COM-компоненты описанный на IDL:
        [id(0x0000001a)]
    HRESULT getParamByteArray(
                    [in] long paramId, 
                    [out, retval] SAFEARRAY(unsigned char)* value);


Изначально студия сгенерировала MFC оболочку на основе COleDispatchDriver выглядит так:
SAFEARRAY * getParamByteArray(long paramId)
{
    static BYTE parms[] = VTS_I4;
    InvokeHelper(0x1a, DISPATCH_METHOD, VT_EMPTY, nullptr, parms, paramId);
}

Это неверный код и я попытался это исправить :
 long getParamByteArray(long paramId, SAFEARRAY **parray) {
    DISPPARAMS dispparams;
    VARIANTARG varArgIn;
    VARIANTARG varArgResult;
    varArgResult.parray =*parray;
    VariantInit(&varArgIn);
    VariantInit(&varArgResult);

    V_VT(&varArgIn) = (VT_INT);
    V_VT(&varArgResult) = (VT_ARRAY | VT_UI1);

    memset(&dispparams, 0, sizeof(DISPPARAMS));
    dispparams.rgvarg = &varArgIn;
    dispparams.cArgs = 1;

    UINT nErrArg;
    EXCEPINFO excepinfo;
    HRESULT hr = m_lpDispatch->Invoke(0x1a, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &dispparams, &varArgResult, &excepinfo, &nErrArg);
    return hr;
}

Вызов данного метода:
CComSafeArray<BYTE> array(1024); 
m_error = p->getParamByteArray(param::LIBFPTR_PARAM_OFD_FISCAL_SIGN, array.GetSafeArrayPtr());

После вызова получаем S_OK и пустой массив SAFEARRAY... Подскажите кто знает как правильно получить возвращаемое значение SAFEARRAY с помощью IDispatch::Invoke?
Получить SAFEARRAY через IDispatch::Invoke
Есть вот такой метод COM-компоненты описанный на IDL:
        [id(0x0000001a)]
    HRESULT getParamByteArray(
                    [in] long paramId, 
                    [out, retval] SAFEARRAY(unsigned char)* value);


Изначально студия сгенерировала MFC оболочку на основе COleDispatchDriver выглядит так:
SAFEARRAY * getParamByteArray(long paramId)
{
    static BYTE parms[] = VTS_I4;
    InvokeHelper(0x1a, DISPATCH_METHOD, VT_EMPTY, nullptr, parms, paramId);
}

Это неверный код и я попытался это исправить :
 long getParamByteArray(long paramId, SAFEARRAY **parray) {
    DISPPARAMS dispparams;
    VARIANTARG varArgIn;
    VARIANTARG varArgResult;
    varArgResult.parray =*parray;
    VariantInit(&varArgIn);
    VariantInit(&varArgResult);

    V_VT(&varArgIn) = (VT_INT);
    V_VT(&varArgResult) = (VT_ARRAY | VT_UI1);

    memset(&dispparams, 0, sizeof(DISPPARAMS));
    dispparams.rgvarg = &varArgIn;
    dispparams.cArgs = 1;

    UINT nErrArg;
    EXCEPINFO excepinfo;
    HRESULT hr = m_lpDispatch->Invoke(0x1a, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &dispparams, &varArgResult, &excepinfo, &nErrArg);
    return hr;
}

Вызов данного метода:
CComSafeArray<BYTE> array(1024); 
m_error = p->getParamByteArray(param::LIBFPTR_PARAM_OFD_FISCAL_SIGN, array.GetSafeArrayPtr());

После вызова получаем S_OK и пустой массив SAFEARRAY...
Также пытался по другому инициализировать varArgResult:
V_VT(&varArgResult) = (VT_BYREF | VT_ARRAY | VT_UI1);
V_ARRAYREF(&varArgResult) = parray;

Результат тот же S_OK и пустой массив. Подскажите кто знает как правильно получить возвращаемое значение SAFEARRAY с помощью IDispatch::Invoke?