JavaScript — вызвать оператор instanceof в JScript на C ++ (IDispatch / IDispatchEx)

У меня есть приложение, которое содержит движок Active Script JScript. В зависимости от версии jscript.dll, он работает до JScript 5.8. Приложение предоставляет множество объектов и методов среде JScript.

Когда скрипт вызывает определенную функцию, с IDL вот так:

HRESULT func(VARIANT varInput);

Я хочу определить, является ли вход instanceof другая функция (то есть, если функция является конструктором, прототип которого находится в цепочке прототипов ввода). В JScript:

input instanceof Error

Как это можно сделать в C ++ с IDispatch / IDispatchEx?

У метода есть доступ к интерфейсам IActiveScript (реализованным движком JScript) и IActiveScriptSite (реализуемым хостом), поэтому можно получить глобальный объект с помощью IActiveScript :: GetScriptDispatch, из которого любой другой конструктор (такой как Error) можно получить.

2

Решение

IDispatch* вы завернули в вариант есть DISPID_VALUE знак равно 0) имущество, которое в случае Error объект выдаст вам строковое значение «[ошибка объекта]».

Вы также можете определить или внедрить функции JScript, такие как:

function IsInstanceOf(object, type) {
return object instanceof type;
}
function IsInstanceOfError(object) {
return IsInstanceOf(object, Error);
}

и перезвоните из вашего кода C ++, используя IDispatch* вы уже придерживаетесь того, чтобы механизм JScript проверил его по определенному типу и вернул вам результат проверки true / false.

0

Другие решения

Я думаю, что Roman R это хороший ответ, но, чтобы минимизировать внедрение кода, вы можете использовать IActiveScriptParse::ParseScriptText превратить любую анонимную функцию JavaScript в IDispatch указатель:

    HRESULT hr = S_OK;
EXCEPINFO ei = { };
CComVariant vIsErrorFunc;
hr = spIActiveScriptParse->ParseScriptText(
OLESTR("(function () { return function (obj) { return obj instanceof Error; }; } )();"),    // pstrCode
NULL,                       // pstrItemName
NULL,                       // punkContent
NULL,                       // pstrDelimiter
0,                          // dwSourceContextCookie
0,                          // ulStartingLineNumber
SCRIPTTEXT_ISEXPRESSION,    // dwFlags
&vIsErrorFunc,              // pvarResult
&ei                         // pexcepinfo
);

Для анонимной функции удобно использовать DISPID DISPID_VALUE который вы можете использовать IDispatch::Invoke, Если у вас есть объект JavaScript в VARIANT Вы можете проверить это следующим образом:

// VARIANT* pvObject -- JavaScript object to test
DISPPARAMS dispParams = { pvObject, 0, 1, 0 };
CComVariant vResult;
hr = V_DISPATCH(&vIsErrorFunc)->Invoke(
DISPID_VALUE,
IID_NULL,
0,
DISPATCH_METHOD,
&dispParams,
&vResult,
NULL,
NULL);

Вы можете упорствовать vIsErrorFunc так что вы можете многократно использовать анонимную функцию или позволить ей выйти из области видимости и собрать мусор. В любом случае, не должно быть длительного воздействия на клиентский код в движке JavaScript.

** РЕДАКТИРОВАТЬ: **

Я обнаружил, что моя оригинальная анонимная функция не работает (вместо VT_DISPATCH я получил VT_EMPTY):

function (obj) { return obj instanceof Error; }

Чтобы обмануть это, я обернул функцию следующим образом:

(
function ()
{
return function (obj) { return obj instanceof Error; }
}
) ()

Я надеюсь, что это объясняет странное выражение в моем примере.

0

С ++, эквивалентный оператору instanceof в Java, — использовать dynamic_cast.
например.,

x instanceof y

будет следующим в C ++:

dynamic_cast<y*>(x) != 0
-1
По вопросам рекламы [email protected]