无法在VARIANT结构中获得BSTR数据的准确位置

时间:2017-07-28 05:39:24

标签: c++ variant bstr

BSTR 结构中读取 VARIANT 值时出现奇怪问题。

我使用以下Javascript代码将数据发送到C ++代码:

external.CppCall("zhttShow", 1, "Y");

在我的C ++代码中的Invoke函数中,我尝试访问该数据:

HRESULT STDMETHODCALLTYPE WebBrowser::Invoke(_In_  DISPID dispIdMember, _In_  REFIID  riid, _In_  LCID lcid, _In_  WORD wFlags, _In_  DISPPARAMS *pp, _Out_opt_ VARIANT *pVarResult, _Out_opt_ EXCEPINFO *pExcepInfo, _Out_opt_ UINT *puArgErr)
{
    if (dispIdMember == 100)
    {
        unsigned int k = pp->cArgs;
        if (k > 0)
        {
            VARIANT *vVariant = &pp->rgvarg[k - 1];
            if ((vVariant->vt & VT_BSTR) == VT_BSTR && vVariant->pvarVal->bstrVal)
            {
                wchar_t *wide = (wchar_t*)(vVariant->pvarVal->bstrVal);
                // other code
            }
        }
    }
}

在上面的代码中, wide 指向未定义的位置。如果我得到 vVariant->pvarVal->bstrVal 的指针,则它指向BSTR值附近的位置:

VARIANT *vVariant = &pp->rgvarg[k - 1];
if ((vVariant->vt & VT_BSTR) == VT_BSTR && vVariant->pvarVal->bstrVal)
{
    wchar_t *wide = (wchar_t*)(&vVariant->pvarVal->bstrVal);
    // other code
}

wide 指向 BSTR 数据8字节的位置,所以改为“zhttShow”字符串,我只能“显示”。如果我将 wide 减去4,我将获得所需的数据。

Bellow是第二个C ++代码的调试屏幕:

enter image description here

问题:

为什么 wide 没有指向BSTR的确切位置?我的代码中有什么错误以及如何修复它?

1 个答案:

答案 0 :(得分:1)

BSTR不是wchar_t*。它可能看起来很相似,但不是。更重要的是,wchar_t*绝对不是BSTR。 BSTR具有结构,一个位于指向值的的头,因此真正的BSTR在地址之前启动几个字节。见BSTR Data Type

  

BSTR是一种复合数据类型,由长度前缀,数据字符串和终止符组成。

这就是您应该始终使用适当的BSTR特定API的原因。最好,使用像_bstr_t这样的编译器支持。要正确地从VARIANT中提取BSTR,我会使用_variant_t Extractor。让编译器处理细节。