【问题标题】:COM - C++ Invoke function return DISP_E_TYPEMISMATCH [duplicate]COM - C++ 调用函数返回 DISP_E_TYPEMISMATCH [重复]
【发布时间】:2021-04-14 07:20:49
【问题描述】:

我目前正在尝试使用 COM 调用软件的 ActiveX 函数。 这是函数声明:

    [
        id(0xa),
        helpcontext(0)
    ]
    HRESULT MAIN_GetVersion (
        [out] short* nStatus,
        [out] BSTR* szStatusMsg,
        [out] BSTR* szVersion
    );

这是我的做法:

short errorCode = 0;
    BSTR errorMessageBSTR =  SysAllocString(L"test");
    BSTR versionBSTR =  SysAllocString(L"test");

    VARIANT result;
    DISPPARAMS params = {NULL, NULL, 0, 0};
    VARIANTARG args[3];
    
    //First argument : Short*
    VariantInit(&args[0]);
    args[0].vt = VT_I2 | VT_BYREF;
    args[0].piVal = &errorCode;
    //Second argument : BSTR*
    VariantInit(&args[1]);
    args[1].vt = VT_BSTR | VT_BYREF;
    args[1].pbstrVal = &errorMessageBSTR;
    //Third argument : BSTR*
    VariantInit(&args[2]);
    args[2].vt = VT_BSTR | VT_BYREF;
    args[2].pbstrVal = &versionBSTR;
    
    params.rgvarg = args;
    params.cArgs = 3;
    
    DISPID dispID;
    char szName[200];
    // Convert down to ANSI
    wchar functionName[] = L"MAIN_GetVersion";
    wchar_t* functionNamePtr = functionName;
    WideCharToMultiByte(CP_ACP, 0, functionName, -1, szName, 256, NULL, NULL);
    CheckHResult(App.pdispVal->GetIDsOfNames(IID_NULL, &functionNamePtr, 1, LOCALE_USER_DEFAULT, &dispID) ,szName , dispID);
    CheckHResult(App.pdispVal->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &params, &result, NULL, NULL), szName , dispID);
    /*
    return :
        DISP_E_TYPEMISMATCH
            One or more of the arguments could not be coerced. The index of the first parameter with the incorrect type within rgvarg is returned in puArgErr.
    */

由于某种原因,此代码不起作用并返回 DISP_E_TYPEMISMATCH。由于某些其他原因,如果我将所有 VARIANT vartype 的强调文本 设置为 VT_EMPTY,它可以工作,但结果 VARIANT 没有返回任何内容。

我尝试驱动的软件的 activeX 实现有可能是错误的吗? 我是不是做错了什么?!

【问题讨论】:

  • @SimonMourier 是的

标签: c++ windows automation com ole


【解决方案1】:

在构建 DISPARAMS 来设置 somes arg 时,您需要按照调用的相反顺序对它们进行排序。就我而言:

//First argument : Short*
VariantInit(&args[2]);
args[2].vt = VT_I2 | VT_BYREF;
args[2].piVal = &errorCode;
//Second argument : BSTR*
VariantInit(&args[1]);
args[1].vt = VT_BSTR | VT_BYREF;
args[1].pbstrVal = &errorMessageBSTR;
//Third argument : BSTR*
VariantInit(&args[0]);
args[0].vt = VT_BSTR | VT_BYREF;
args[0].pbstrVal = &versionBSTR;

short 是我的 VARIANT ARRAY 的最后一个 VARIANT。

【讨论】:

    猜你喜欢
    • 2017-12-16
    • 2013-06-28
    • 2018-07-14
    • 2023-03-14
    • 1970-01-01
    • 2018-05-14
    • 1970-01-01
    • 2020-03-15
    • 2013-06-14
    相关资源
    最近更新 更多