Как извлечь все предлагаемые типы интерфейсов из COM-идентификатора? - PullRequest
0 голосов
/ 21 февраля 2019

Моя цель - создать мостовой код, который позволяет вызывать COM-интерфейс в Java.Я успешно использую JNA, поскольку я получаю дескриптор интерфейса и могу успешно работать с большинством функциональных возможностей интерфейса.

У меня есть вопрос относительно нескольких интерфейсов, которые похожи на следующий шаблон (ядумаю, что фрагмент является автономным):

[
  odl,
  uuid(4D27AA78-B622-42E7-A237-3DA76B14A23D),
  helpstring("IVariables Interface"),
  dual,
  oleautomation
]
interface IVariables : IDispatch {
    [id(0x00000001), propget, helpstring("property Application")]
    HRESULT Application([out, retval] IDispatch** pVal);
    [id(0x00000002), propget, helpstring("property Parent")]
    HRESULT Parent([out, retval] IDispatch** pVal);
    [id(0x00000003), propget, helpstring("property Count")]
    HRESULT Count([out, retval] long* pnCount);
    [id(00000000), propget, helpstring("property Item")]
    HRESULT Item(
                    [in] VARIANT index, 
                    [out, retval] IVariable** pVal);
    [id(0xfffffffc), propget, helpstring("property _NewEnum")]
    HRESULT _NewEnum([out, retval] IUnknown** ppEnum);
    [id(0x00000004), helpstring("method Add")]
    HRESULT Add(
                    [in] BSTR Name, 
                    [in, optional] VARIANT Value, 
                    [out, retval] IVariable** pVal);
    [id(0x00000005), helpstring("method Remove")]
    HRESULT Remove([in] VARIANT index);
};

Если этот интерфейс импортирован в Visual Studio и используется в проекте C #, то C # обнаруживает, что приведенный выше реализует интерфейс IEnumerator ипозволяет перебирать элементы.Более того, C # даже знает итеративный тип, являясь 'IVariable'.

Q1: Как C # или его импортер COM-интерфейса делает вывод, что вышеприведенные IVariables реализуют IEnumerator и перечисляемые элементыимеют тип 'IVariable'?

Очевидно, что строка

[id(0xfffffffc), propget, helpstring("property _NewEnum")]

должна сработать.Но хотя я нашел такую ​​же конструкцию в других IDL, я не могу найти никакого объяснения этому в Google.Возможно, это связано с тем, что я не получаю никакой информации о типах свойств из IDL, см.

    [id(0x00000002), propget, helpstring("property Parent")]

в приведенном выше IDL.Нет ни типа «Родитель», ни типа «Родитель».Таким образом:

Q2: возможно ли получить тип свойства COM из его IDL и если да, то как?

Наконец, при импорте указанных выше типов в C #вышеуказанный IDL фактически не используется.Вместо этого импортер ожидает, что исполняемый файл приложения с поддержкой OLE прочитает свою библиотеку типов (аналогично инструменту Microsoft oleview.exe).Это подводит меня к моему последнему вопросу:

Q3: есть ли API, который можно использовать для запроса интерфейса OLE исполняемого файла, и предлагает ли это дополнительные метаданные?

Спасибо за идеи.

1 Ответ

0 голосов
/ 21 февраля 2019

1) потому что dispid хорошо известен: DISPID_NEWENUM (-4), который обозначает перечислитель.Тип элемента (IVariable) может быть выведен из элемента Item (индексатора), который использует 0 (DISPID_VALUE).

DISPID_NEWENUM -4

Это ОБЯЗАТЕЛЬНО обозначаетDISPID связан с методом _NewEnum, который ДОЛЖЕН иметь следующую подпись.

HRESULT _NewEnum ([out, retval] IEnumVARIANT ** ppenum);

или

HRESULT _NewEnum ([out, retval] IUnknown ** ppenum);

2) yes, если тип свойства указан в idl (duh), но здесь вы смотрите на чистый интерфейс поздней привязки (Только IDispatch), что является полностью динамическим, поэтому нет, в данном случае

3) .IDL не используется, поскольку формат .TLB эквивалентен и программируется с помощью ITypeLib и другие.Только компилятор MIDL использует IDL.Во время выполнения в общем случае доступно немного больше, чем TLB.COM в простейшем виде в основном нуждается только в IUnknown и все.

...