在C ++中用JScript调用instanceof运算符(IDispatch / IDispatchEx)

时间:2012-09-08 18:54:35

标签: javascript c++ com jscript idispatch

我有一个托管Active Script JScript引擎的应用程序。根据jscript.dll的版本,它可以运行到JScript 5.8。该应用程序向JScript环境公开了许多对象和方法。

当脚本调用某个函数时,IDL如下:

HRESULT func(VARIANT varInput);

我想确定输入是否是instanceof另一个函数(即,如果函数是一个构造函数,其原型在输入的原型链中)。在JScript中:

input instanceof Error

如何使用IDispatch / IDispatchEx在C ++中完成此操作?

该方法可以访问IActiveScript(由JScript引擎实现)和IActiveScriptSite(由主机实现)接口,因此可以使用IActiveScript :: GetScriptDispatch获取全局对象,其中任何其他构造函数(例如可以检索Error)。

3 个答案:

答案 0 :(得分:0)

您已包装到变体中的IDispatch*具有DISPID_VALUE(= 0)属性,如果Error对象将为您提供字符串值“[object]错误]”。

您还可以定义或注入JScript函数,如:

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

并使用IDispatch*从您的C ++代码中调用它们,您已经按住它让JScript引擎根据特定类型对其进行检查,并返回此类检查的真/假结果。

答案 1 :(得分: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_VALUE的DISPID,您可以使用IDispatch::Invoke触发。如果VARIANT中有JavaScript对象,则可以按如下方式对其进行测试:

// 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_EMPTY而不是VT_DISPATCH):

function (obj) { return obj instanceof Error; }

为了欺骗它,我将函数包装如下:

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

我希望这能解释我的例子中的奇怪表达。

答案 2 :(得分:-1)

与Java的instanceof运算符等效的C ++是使用dynamic_cast。 如,

x instanceof y

将在C ++中使用以下内容:

dynamic_cast<y*>(x) != 0