Javascript 基于脉轮和IDispatch的索引属性

Javascript 基于脉轮和IDispatch的索引属性,javascript,winapi,chakra,Javascript,Winapi,Chakra,我正在使用本机windows API和chakrart JavaScript引擎创建一个可编写脚本的应用程序。 我的IDL中有如下接口: [oleautomation, dual, nonextensible, uuid(...)] interface IMyInterface : IDispatch { [id(MYDISPID_EVENT), propget] HRESULT Event(BSTR strEventName, [out, retval] IDispatch ** ppHand

我正在使用本机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引擎中(通过使用JSVariantOvalue,然后在当前上下文的全局对象上设置属性)。但是,当我尝试设置事件处理程序时,会收到异常消息“Object不支持此属性或方法”

我尝试了以下语法变体:

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对象是如此。这可能只是脉轮互操作层中的不兼容吗?

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

让应用程序对象实现一个propget for事件,该事件返回一个具有自定义(非双接口)IDispatch实现的对象。该对象保留名称到DISPID的映射,并且每当通过GetIDsOfNames请求未知名称时,将返回以前未分配的DISPID


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

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

让应用程序对象实现一个propget for事件,该事件返回一个具有自定义(非双接口)IDispatch实现的对象。该对象保留名称到DISPID的映射,并且每当通过GetIDsOfNames请求未知名称时,将返回以前未分配的DISPID


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

因此我没有答案,但我将尝试做一些类似的事情,我很好奇您到底是如何注册本机对象的?您是否创建了包含对象IDispatch指针的VT_DISPATCH类型的变量,将其传递给JSVariantOvalue,然后将该值注册为全局对象的属性?这正是我所做的。这也意味着我被困在使用脉轮而不是使用脉轮核心,脉轮核心是引擎的便携式部件,但IDispatch不是,所以。。。我还编写了一个函数,它接受IDispatch和ITypeInfo指针,并将所有可分派成员注册为全局的属性。这是因为JavaScript运行时宿主没有类似IActiveScript::AddNamedItem的SCRIPTITEM_GLOBALMEMBERS标志的内容。很抱歉删除了几次我的回复,我是盲人,并且编辑框在我的屏幕阅读器上表现不佳。所以我没有答案给你,但我将尝试做一些类似的事情,我很好奇你到底是如何注册本机对象的?您是否创建了包含对象IDispatch指针的VT_DISPATCH类型的变量,将其传递给JSVariantOvalue,然后将该值注册为全局对象的属性?这正是我所做的。这也意味着我被困在使用脉轮而不是使用脉轮核心,脉轮核心是引擎的便携式部件,但IDispatch不是,所以。。。我还编写了一个函数,它接受IDispatch和ITypeInfo指针,并将所有可分派成员注册为全局的属性。这是因为JavaScript运行时宿主没有类似IActiveScript::AddNamedItem的SCRIPTITEM_GLOBALMEMBERS标志的内容。很抱歉删除了几次我的回复,我是盲人,编辑框在我的屏幕阅读器上表现不好。我设法与ChakraRT团队联系,他们确认IDispatch支持是赤裸裸的,索引属性无法工作。也就是说,只要只需要一个索引器(如我的示例中所示),并且该值可以转换为可用字符串(也如我的示例中所示),我给出的解决方法就会起作用最好只使用方法路线(我最初的问题中的GetEvent/SetEvent)。我与ChakraRT团队进行了联系,他们确认IDispatch支持是基本的,索引属性不起作用。也就是说,只要只需要一个索引器(如我的示例中所示),并且该值可以转换为可用字符串(也如我的示例中所示),我给出的解决方法就会起作用最好只使用方法路线(我最初的问题中的GetEvent/SetEvent)。