我正在使用本机Windows API和chakrart JavaScript引擎创建可编写脚本的应用程序。
我的IDL中有如下界面:

[oleautomation, dual, nonextensible,
uuid(...)]
interface IMyInterface : IDispatch
{
[id(MYDISPID_EVENT), propget] HRESULT Event(BSTR strEventName, [out, retval] IDispatch ** ppHandler);
[id(MYDISPID_EVENT), propput] HRESULT Event(BSTR strEventName, IDispatch * pHandler);
};


我已经能够轻松地将原始对象添加到chakrart引擎中(通过使用JsVariantToValue,然后在当前上下文的全局对象上设置属性)。但是,当我尝试设置事件处理程序时,出现异常消息“对象不支持此属性或方法”。

我尝试了以下语法变体:

object.Event["foo"] = handler;
object.Event("foo", handler);
object.put_Event("foo", handler);
object.Event("foo") = handler;


最后一点与使用vbscript的方式差不多:

object.Event("foo") = GetRef("handler)


如果我像下面那样在IDL中使用方法语法,那么我将尽可能地使用属性分配。

[id(MYDISPID_GETEVENT)] HRESULT GetEvent(BSTR strEventName, [out, retval] IDispatch ** ppHandler);
[id(MYDISPID_SETEVENT)] HRESULT SetEvent(BSTR strEventName, IDispatch * pHandler);


还要注意,简单的属性分配确实有效,只有当我尝试索引属性时,它才会中断。我确实知道JavaScript与object [prop]语法有很大不同,至少对于本机JavaScript对象而言。这可能仅仅是在chakrart互操作层中的不兼容?

最佳答案

我已经确认了一种使用所需语法(App.Event ['foo'] = someHandler;)执行此操作的方法。如前所述,我已经知道JavaScript将name ['foo']视为对name的成员查找

让App对象实现Event的属性,该属性返回具有自定义(非双重接口)IDispatch实现的对象。该对象保留名称到DISPID的映射,并且每当通过GetIDsOfNames请求未知名称时,都会返回以前未分配的DISPID。

请注意,为了遵守IDispatch的规则,即使以后将空处理程序分配给给定名称,该对象也需要跟踪名称,以便始终为特定名称返回相同的DISPID。

关于javascript - 基于Chakra和IDispatch的索引属性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46836822/

10-12 12:53
查看更多