Passer un objet de JavaScript à C ++
-
14-11-2019 - |
Question
j'ai trouvé Passer un tableau de JavaScript à C ++ Solution, mais j'ai une autre tâche: passer un objet De JavaScript à C ++ (si j'utilise iwebbrowser2 avec iDispatch)
Je veux dire que j'ai besoin d'appeler la méthode C ++ via window.external.method avec l'argument de l'objet JavaScript
var obj = {name: "Petr", group: "Friend"};
window.external.myMethod(obj);
Comment accéder au membre de l'objet "nom", "groupe", etc.?
La solution
Vous pouvez accéder aux propriétés de l'objet via le IDispatch
interface et ses méthodes GetIDsOfNames
et Invoke
.
En fonction de votre définition de myMethod
, tu devrais recevoir obj
comme un VARIANT
ou un IDispatch *
dans votre code C ++. Si un VARIANT
, vt
devrait être VT_DISPACTH
, auquel cas vous pouvez déréférence en toute sécurité pdispval
.
Une fois que vous avez un IDispatch
pointeur, vous pouvez utiliser GetIDsOfNames
pour obtenir le DISPID
Pour une propriété qui vous intéresse comme tel:
_bstr_t sPropertyName = L"myProperty";
DISPID dispid = 0;
HRESULT hr = pDispatch->GetIDsOfNames(IID_NULL, &sPropertyName, 1, LOCALE_SYSTEM_DEFAULT, &dispid);
if(SUCCEEDED(hr))
{
...
Une fois que vous avez réussi votre DISPID
, tu dois appeler Invoke
différemment selon si vous souhaitez obtenir une valeur, définir une valeur ou appeler une méthode.
Par exemple, pour obtenir une valeur:
VARIANT vValue;
hr = pDispatch->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, 0, &vValue, 0, 0);
if(SUCCEEDED(hr))
{
...
Voir la documentation pour Invoke
Pour plus d'informations sur les différentes permutations lors de l'appel.
Autres conseils
Si vous avez juste besoin de lire les champs d'objet, le moyen le plus flexible est d'utiliser JSON.
Sur votre page Web Utilisation du côté:
var obj = {name: "Petr", groupe: "ami"}; window.external.mymethod (json.stringify (obj));
Du côté C ++, définissez MyMethod () pour accepter un argument de chaîne unique. Puis utilisez un C ++ JSON Parser Pour analyser cet argument dans un objet lisible.
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;
}
et exemple de code de 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;