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

1

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

  • 0
    Так что у меня нет ответа для вас, но я собираюсь попытаться сделать что-то подобное, и мне любопытно, как именно вы зарегистрировали свой нативный объект? Вы создали VARIANT типа VT_DISPATCH, содержащий указатель IDispatch вашего объекта, передали его в JsVariantToValue, а затем зарегистрировали это значение как свойство глобального объекта?
  • 1
    Это именно то, что я сделал. Это также означает, что я застрял с помощью ChakraRT вместо того, чтобы использовать ChakraCore, ChakraCore - это переносимые части движка, а IDispatch - нет, поэтому ... Я также написал функцию, которая использует указатели IDispatch и ITypeInfo и регистрирует все отправляемые члены как свойства глобальных. Это связано с тем, что хостинг JavaScript во время выполнения не имеет ничего общего с флагом SCRIPTITEM_GLOBALMEMBERS IActiveScript :: AddNamedItem. И извините за удаление моего ответа несколько раз, я слепой, и окно редактирования плохо работало с моей программой чтения с экрана.
Теги:
winapi
chakra

1 ответ

0
Лучший ответ

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

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

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

  • 0
    Мне удалось связаться с командой ChakraRT, и они подтвердили, что поддержка IDispatch совершенно необязательна и что индексированные свойства не будут работать. Это сказанное до тех пор, пока необходим только один индексатор (как в моем примере), и это значение может быть преобразовано в пригодную для использования строку (также как в моем примере), обходной путь, который я дал, будет работать. Однако, если вам нужен объект для работы в несколько языков (особенно если вам нужны JavaScript и VBScript), вероятно, было бы лучше просто пойти по пути метода (GetEvent / SetEvent из моего первоначального вопроса).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню