QueryInterface возвращает неверный интерфейс в JACOB 1.17

Я пытаюсь использовать JACOB 1.17 (последняя стабильная версия) для доступа к 64-битному COM-серверу в процессе, то есть MyObject-x64.dll.

Мой CoClass имеет два двойных интерфейса: IFoo (по умолчанию) и IBar. IFoo содержит foo_method(), а IBar содержит bar_method(). Оба метода имеют идентификатор отправки 1.

Мой код Java:

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.LibraryLoader;
import com.jacob.com.Variant;

// ...

ActiveXComponent my_object = new ActiveXComponent("MyObject.MyClass");    // OK
Dispatch.call(my_object, "foo_method");    // OK
Dispatch ibar = my_object.QueryInterface("{DE3FF217-120B-4F1E-BEF5-098B8ABDEC1F}");    // OK
Dispatch.call(ibar, "bar_method");    // Exception - "Can't map names to dispid:bar_method"
Dispatch.getIDOfName(ibar, "bar_method");    // Exception - "Can't map names to dispid:bar_method"
Dispatch.call(ibar, "foo_method");    // OK, executes foo_method
Dispatch.call(ibar, 1);    // OK, executes foo_method

Итак, кажется, что либо QueryInterface вернул неверный интерфейс, либо функция call в ibar вызывает интерфейс по умолчанию вместо результата QueryInterface.

Я быстро просмотрел исходный код JNI для jacob-1.17-x64.dll и не вижу какой-либо очевидной проблемы с реализацией QueryInterface или с реализацией call, хотя раньше я не просматривал код JNI, поэтому я могу пропустить что-то очевидное.

Вместе с JACOB поставляется образец samples/com/jacob/samples/atl, который обращается к нескольким интерфейсам и использует QueryInterface так же, как и я. Однако я не могу запустить этот пример, так как для него требуется MultiFace.dll, который не предоставляется. (Источник предоставлен, но это исходный код, специфичный для MSVC++, и я не использую MSVC++).

IID в QueryInterface определенно правильный, и мой объект точно не поврежден; Я могу получить доступ к IBar, используя бесплатную пробную версию одного из коммерческих мостов Java-COM, а также из Visual Basic.

JACOB прослушивается или я что-то не так делаю?

Использование JRE 1.7.0_51-b13.


person M.M    schedule 16.03.2014    source источник
comment
Обновление: похоже, это ошибка в C++Builder XE и более поздних версиях; объекты, которые используют DAX для своей реализации, имеют ошибочные реализации IDispatch. Как только я подтвержу это, я убью эту ветку.   -  person M.M    schedule 18.03.2014


Ответы (1)


На самом деле, Джейкоб в порядке. Проблема в том, что C++Builder XE5 содержит ошибки в реализации IDispatch. Если вы QueryInterface для IDispatch плюс IID нужного интерфейса, вы получите действительный указатель, однако на самом деле он указывает на исходный интерфейс, из которого вы запросили, а не на новый.

Все остальные методы доступа должны использовать привязку vtable, чтобы не возникало проблем.

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

Пока обходного пути не нашел.

person M.M    schedule 02.05.2014