2

我有一个托管 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)取回。

4

3 回答 3

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. 如果您在 a 中有一个 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_EMPTY 而不是 VT_DISPATCH):

function (obj) { return obj instanceof Error; }

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

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

我希望这可以解释我的示例中的奇怪表达。

于 2013-03-20T05:04:09.150 回答
0

IDispatch*您包装到变体中的有一个( DISPID_VALUE= 0) 属性,如果是Errorobject,它会给您一个字符串值“[object Error]”。

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

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

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

于 2012-09-10T10:49:37.857 回答
-1

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

x instanceof y

在 C++ 中将是以下内容:

dynamic_cast<y*>(x) != 0
于 2012-09-08T23:59:48.747 回答