将对象从 Javascript 传递到 C++

Passing an object from Javascript to C++

本文关键字:C++ Javascript 对象      更新时间:2023-10-16

我发现将数组从Javascript传递到C++解决方案,但我还有另一个任务:将对象从Javascript传递到C++(如果我将IWebBrowser2与IDispatch一起使用)

我的意思是我需要通过 window.external.method 使用 JavaScript 对象参数调用C++方法

var obj = {name: "Petr", group: "Friend"};
window.external.myMethod(obj);

如何访问对象成员"名称","组"等?

您可以通过 IDispatch 接口及其方法 GetIDsOfNamesInvoke 访问对象的属性。

根据您对myMethod的定义,您应该在C++代码中以VARIANTIDispatch *的形式接收obj。如果是VARIANTvt应该VT_DISPACTH,在这种情况下,你可以安全地取消引用pdispval

获得IDispatch指针后,您可以使用GetIDsOfNames获取您感兴趣的属性的DISPID,如下所示:

_bstr_t sPropertyName = L"myProperty";
DISPID dispid = 0;
HRESULT hr = pDispatch->GetIDsOfNames(IID_NULL, &sPropertyName, 1, LOCALE_SYSTEM_DEFAULT, &dispid);
if(SUCCEEDED(hr))
{
    ...

成功收到DISPID后,您必须根据是要获取值、设置值还是调用方法,以不同的方式调用Invoke

例如,要获取值:

    VARIANT vValue;
    hr = pDispatch->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, 0, &vValue, 0, 0);
    if(SUCCEEDED(hr))
    {
        ...

有关调用它时不同排列的详细信息,请参阅Invoke文档。

如果您只需要能够读取对象字段,最灵活的方法是使用 JSON。

在您的网页端使用:

var obj = {name: "Petr", group: "Friend"};window.external.myMethod(JSON.stringify(obj));

在C++端定义 myMethod() 以接受单个字符串参数。然后使用 C++ JSON 解析器将此参数解析为可读对象。

static HRESULT 
IDispatch_VarGet (IDispatch *pRDisp, LPOLESTR Name, VARIANT *pVarRes)
{
    DISPPARAMS DispParams;
    DISPID dispid;
    HRESULT hr;
    if ((hr = IDispatch_GetIDsOfNames (pRDisp, &IID_NULL,
                &Name, 1, LOCALE_SYSTEM_DEFAULT, &dispid)))
        return hr;
    ZeroMemory (&DispParams, sizeof (DispParams));
    hr = IDispatch_Invoke (pRDisp, dispid, &IID_NULL,
            LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET,
            &DispParams, pVarRes, NULL, NULL);
    return hr;
}

static HRESULT 
IDispatch_VarPut (IDispatch *pRDisp, LPOLESTR Name, VARIANT *pVarArg)
{
    DISPPARAMS DispParams;
    DISPID dispid, ndispid;
    HRESULT hr;
    if ((hr = IDispatch_GetIDsOfNames (pRDisp, &IID_NULL,
                &Name, 1, LOCALE_SYSTEM_DEFAULT, &dispid)))
        return hr;
    ndispid = DISPID_PROPERTYPUT;
    DispParams.rgvarg = pVarArg;
    DispParams.rgdispidNamedArgs = &ndispid;
    DispParams.cArgs  = 1;
    DispParams.cNamedArgs = 1;
    hr = IDispatch_Invoke (pRDisp, dispid, &IID_NULL,
            LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYPUT,
            &DispParams, NULL, NULL, NULL);
    return hr;
}

static HRESULT 
IDispatch_StrPut (IDispatch *pRDisp, LPOLESTR Name, LPOLESTR StrVal)
{
    VARIANT varg;
    HRESULT hr;
    VariantInit (&varg);
    V_VT   (&varg) = VT_BSTR;
    V_BSTR (&varg) = SysAllocString (StrVal);
    hr = IDispatch_VarPut (pRDisp, Name, &varg);
    VariantClear (&varg);
    return hr;
}

static HRESULT 
IDispatch_IntPut (IDispatch *pRDisp, LPOLESTR Name, int IntVal)
{
    VARIANT varg;
    HRESULT hr;
    VariantInit (&varg);
    V_VT (&varg) = VT_I4;
    V_I4 (&varg) = IntVal;
    hr = IDispatch_VarPut (pRDisp, Name, &varg);
    VariantClear (&varg);
    return hr;
}

if ((hr = IDispatch_StrPut (pRDisp, L"code", buff)))
    return hr;
if ((hr = IDispatch_IntPut (pRDisp, L"state", state)))
    return hr;

{
    // ...
    VariantInit (&varg);
    if ((hr = IDispatch_VarGet (pRDisp, L"code", &varg)))
    {
        VariantClear (&varg);
        return hr;
    }
    if (V_VT (&varg) == VT_BSTR)
    // ...
    VariantClear (&varg);
    return hr;
}

和贾夫代码示例...

var frec = {code:'', state:0};
frec.code = row.cells[0].innerHTML;
external.FeatureStateChg (frec);
_featState (row.cells[2], frec.state);

var frec = {code:'', name:'', state:0};
if (!external.FeaturesEnum (frec, i))
    break;