Передача объекта из Javascript в C ++ - PullRequest
3 голосов
/ 17 мая 2011

Я нашел Передача массива из Javascript в C ++ решение, но у меня есть другая задача: Передача объекта из Javascript в C ++ (если я использую IWebBrowser2 с IDispatch)

Я имею в виду, что мне нужно вызвать метод C ++ через window.external.method с аргументом объекта JavaScript

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

Как получить доступ к элементу объекта "имя", "группа" и т. Д.?

Ответы [ 3 ]

2 голосов
/ 18 мая 2011

Вы можете получить доступ к свойствам объекта через интерфейс IDispatch и его методы GetIDsOfNames и Invoke.

В зависимости от вашего определения myMethod, вы должны получить obj в виде VARIANT или IDispatch * в вашем коде C ++. Если VARIANT, vt должно быть 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 для получения дополнительной информации о различных перестановках при его вызове.

0 голосов
/ 19 декабря 2013
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;
}

и пример кода jave ...

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;
0 голосов
/ 17 мая 2011

Если вам просто нужно прочитать поля объекта, наиболее гибкий способ - использовать JSON.

На стороне вашей веб-страницы используйте:

var obj = {name: "Petr", группа: "Friend"}; window.external.myMethod (JSON.stringify (OBJ));

На вашей стороне C ++ определите myMethod () для принятия единственного строкового аргумента. Затем используйте синтаксический анализатор C ++ для анализа этого аргумента в читаемый объект.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...