【问题标题】:How to convert a JavaScript object to access its data from C++?如何转换 JavaScript 对象以从 C++ 访问其数据?
【发布时间】:2014-06-19 15:29:27
【问题描述】:

我在我的 C++ (MFC) 应用程序中使用嵌入式 IE ActiveX 控件。嵌入的 IE 有一个 JavaScript 方法,它使用以下(简化的)JavaScript 将数据传回我的 C++ 应用程序:

function passDataTocpp()

{   
    return {key1: 134, key2:'value2'};

}

当我在我的 C++ 代码中收到它时,我得到一个 VT_DISPATCH 类型的 VARIANT。我能够找到 this example 将数组转换为 C++ 可访问数据,但这似乎不适用于关联数组(或对象)。

知道如何访问这些数据吗?

【问题讨论】:

    标签: javascript c++ arrays mfc atl


    【解决方案1】:

    IDispatch::GetIdsOfNamesIDispatch::Invoke(DISPID_PROPGET)。如果您甚至不知道该对象具有哪些属性,请查询 IDispatchEx 并使用 GetNextDispID 枚举它们。

    由于您使用的是 ATL,CComDispatchDriverIDispatch 的便捷包装器(但不是 IDispatchEx - 您必须直接调用该包装器)。出于某种原因,它没有记录在 MSDN 中。在 atlcomcli.h 中查找 CComPtr<IDispatch> 专业化,它相当简单。 CComDispatchDriver 是它的 typedef。

    【讨论】:

      【解决方案2】:

      在 C++ 方面,代码可能如下所示(在 Igor 的回答中解释):

      STDMETHOD(Foo)(VARIANT vValue)
      {
          ATLASSERT(vValue.vt == VT_DISPATCH);
          CComPtr<IDispatch>& pValue = reinterpret_cast<CComPtr<IDispatch>&>
              (vValue.pdispVal);
          CComVariant vItemValue;
          const HRESULT nResult = pValue.GetPropertyByName(L"key1", &vItemValue);
          // vItemValue is VT_I4 134 here
      

      【讨论】:

        【解决方案3】:

        按照@IgorTandetnik 的建议,我想出了以下似乎可以完成这项工作的方法(虽然它是一个伪代码):

        BOOL VariantToObjectProperties(CComVariant& var)
        {
            HRESULT hr;
        
            if (var.vt != VT_DISPATCH)
                return FALSE;
        
            CComPtr<IDispatch> pDispatch = var.pdispVal;
        
            CComQIPtr<IDispatchEx> pDispatchEx;
            if(FAILED(hr = pDispatch->QueryInterface(IID_IDispatchEx, (void **)&pDispatchEx)))
                return FALSE;
        
            BSTR bstrName;
            DISPID dispid;
        
            //Assume success
            BOOL bRes = TRUE;
        
            //Enumerate object names
            hr = pDispatchEx->GetNextDispID(fdexEnumAll, DISPID_STARTENUM, &dispid);
            while (hr == NOERROR)
            {
                if(SUCCEEDED(hr = pDispatchEx->GetMemberName(dispid, &bstrName)))
                {
                    // get DISPID of item
                    DISPID dispidIndex = 0;
                    LPOLESTR pIndex = reinterpret_cast<LPOLESTR>(const_cast<WCHAR *>(bstrName));
                    if(SUCCEEDED(hr = pDispatch->GetIDsOfNames(IID_NULL, &pIndex, 1, LOCALE_USER_DEFAULT, &dispidIndex)))
                    {
                        CComVariant varItem;
                        DISPPARAMS dispParams = {0};
                        if(SUCCEEDED(hr = pDispatch->Invoke(dispidIndex, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispParams, &varItem, NULL, NULL)))
                        {
                            //Object's property name is in 'bstrName'
                            //Object's property value is in 'varItem'
                        }
                        else
                        {
                            ASSERT(NULL);
                            bRes = FALSE;
                        }
                    }
                    else
                    {
                        ASSERT(NULL);
                        bRes = FALSE;
                    }
                }
        
                SysFreeString(bstrName);
                hr = pDispatchEx->GetNextDispID(fdexEnumAll, dispid, &dispid);
            }
        
            return bRes && hr == S_FALSE;
        }
        

        【讨论】:

          猜你喜欢
          • 2016-07-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-03
          相关资源
          最近更新 更多