如何转换 JavaScript 对象以从 C++ 访问其数据?
Posted
技术标签:
【中文标题】如何转换 JavaScript 对象以从 C++ 访问其数据?【英文标题】:How to convert a JavaScript object to access its data from 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++ 可访问数据,但这似乎不适用于关联数组(或对象)。
知道如何访问这些数据吗?
【问题讨论】:
【参考方案1】:IDispatch::GetIdsOfNames
,IDispatch::Invoke(DISPID_PROPGET)
。如果您甚至不知道该对象具有哪些属性,请查询 IDispatchEx
并使用 GetNextDispID
枚举它们。
由于您使用的是 ATL,CComDispatchDriver
是 IDispatch
的便捷包装器(但不是 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;
【讨论】:
以上是关于如何转换 JavaScript 对象以从 C++ 访问其数据?的主要内容,如果未能解决你的问题,请参考以下文章
如何附加调试器以从托管(C#)包装器进入本机(C++)代码?
将 QJsonObject 转换为 Javascript 对象
如何将 AsyncTask 转换为 Retrofit 以从 Android 中的 WCF Webservice 获取数据