我认为 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; }
}
) ()
我希望这可以解释我的示例中的奇怪表达。