Индексированные свойства на основе чакр и IDispatch

Я создаю приложение с поддержкой сценариев, используя собственный API Windows и движок JavaScript chakrart. У меня есть интерфейсы, подобные следующему в моем 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. Возможно, это просто несовместимость в слое взаимодействия чакрарта?

1 ответ

Решение

Я подтвердил способ выполнить это с нужным синтаксисом (App.Event['foo'] = someHandler;). Как уже упоминалось, я уже знал, что JavaScript рассматривает имя ['foo'] как поиск члена по имени

Пусть объект App реализует пропет для Event, который возвращает объект с пользовательской реализацией IDispatch (не с двойным интерфейсом). Этот объект хранит карту имен в DISPID, и всякий раз, когда через GetIDsOfNames запрашивается неизвестное имя, возвращается ранее неназначенный DISPID.

Обратите внимание, что для соответствия правилам IDispatch объект должен отслеживать имена, даже если для данного имени позднее назначается нулевой обработчик, так что один и тот же DISPID всегда будет возвращаться для определенного имени.

Другие вопросы по тегам