|
|
|
Proxin |
|
||||
Опытный Профиль Группа: Участник Сообщений: 363 Регистрация: 21.6.2008 Репутация: нет Всего: 3 |
Всем привет, возник вопрос. Хочу создать com-интрефейс, и от него же унаследовать ещё один
Делаю их реализацию
Но при попытке вызвать QueryInterface для интерфейса ISomeOther и IMyInterface из delphi, с указателем на мой объект класса CSomeOther и CMyInterface соответственно, вылетает исключение. В чём здесь ошибка? Мне нужно что-то типа виртуального наследования классов в с++, чтобы в ISomeOther можно было вызывать и fA(), и fB(). Насколько прочитал, это невозможно, в com-интерфейсах класс-реализатор должен явно имплементировать все методы интерфейсов, на которые он опирается. Что с этим можно сделать? Это сообщение отредактировал(а) Proxin - 20.9.2016, 22:39 |
||||
|
|||||
xvr |
|
|||
Эксперт Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 8 Всего: 223 |
Как у вас реализован метод QueryInterface в классах CMyInterface и CSomeOther ? В последнем он должен уметь отдавать оба интерфейса (IMyInterface и ISomeOther), а в первом - только один (IMyInterface)
Имплементировать можно по разному, в том числе и с помощью наследования реализации (что вы и пытались сделать) |
|||
|
||||
Proxin |
|
||||
Опытный Профиль Группа: Участник Сообщений: 363 Регистрация: 21.6.2008 Репутация: нет Всего: 3 |
в, общем, вот так вот у меня
входит в метод QueryInterface обьекта CSomeOther, вылетает на строке AddRef() upd понял, кажется, в чём ошибка, но как её избежать - нет. АddRef надо проводить непосредственно к тому типу, которого есть этот объект. Если брать IUnknown, то ловлю акцесс виолейшон в c++, и, соответсвтенно, приведение полученого указателя методом IInterface(Ptr) в процедуре supports ( в дельфи ) и даёт исключение. Как с этим быть? почесав голову, добавляю. в дельфи получилось сделать IUnknown(Ptr).QueryInterface(ISomeOther,pSomeOther), Ptr получил простой экспортируемой функцией из dlll, которая возварщает мне объект типа IUnknown*, который получен с помощью dynamic_cast. с++ в ответ на QueryInterface мне передаёт dynamic_cast<ISomeOther*>(this). но при этом при вызове метода pB из pSomeOther со свежеполученного интерфейса опять валится av. интерфейс в дельфи задекларирован так же, как и в c++, с поправками:
Это сообщение отредактировал(а) Proxin - 21.9.2016, 14:49 |
||||
|
|||||
xvr |
|
||||||||
Эксперт Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 8 Всего: 223 |
В в качестве ppvObject случайно не NULL передали?
Не обязательно. У вас один и тот же экземпляр AddRef на все ваши интерфейсы. так что ломаться не должно. кстати, в QueryInterface можно просто позвать AddRef, без всяких указателей.
Не должно. Проверьте, что в Ptr
А вот это неправильно. У вас по факту 2 штуки IUnknown интерфейсов - один в составе IMyInterface, второй в составе ISomeOther. QuaryInterface должна возвращать один и тот же указатель для запросов IUnknown через любой из своих интерфейсов. dynamic_cast это не гарантирует.
Не вижу в коде QueryInterface никаких dynamic_cast Кстати, а как у вас сами объекты (CMyInterface и CSomeOther) создаются? Может они вообще не инициализированны? Тогда будет валится. |
||||||||
|
|||||||||
Proxin |
|
||||||
Опытный Профиль Группа: Участник Сообщений: 363 Регистрация: 21.6.2008 Репутация: нет Всего: 3 |
Нет, у меня объекты в с++ dll создаются по-нормальному.
вычистил все динамик-касты, ради интереса, QueryInterface у меня, как в предыдущем сообщении. Попробовал тут же получить указатель на свой интерфейс для последующего использования, как хочу сделать в дельфи.
всё работает, как часы. тут же в дельфи делаю ( программа - хост для сишной длл, длл полностью загружена и инициализирована )
И что с этим делать? Все мозги уже себе сломал. И да, при одиночном наследовании ( только от IUnknown, без второго уровня, и, соответственно без virtual в реализации сишных классов ) интерфейсы вышеозначенным путём в дельфи возвращаются и используются абсолютно корректно. Это сообщение отредактировал(а) Proxin - 21.9.2016, 21:42 |
||||||
|
|||||||
xvr |
|
||||
Эксперт Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 8 Всего: 223 |
Ой! Только сейчас заметил:
virtual в наследовании делает нечто, что несовместимо ни с кем (в том числе и с COM) |
||||
|
|||||
Proxin |
|
|||
Опытный Профиль Группа: Участник Сообщений: 363 Регистрация: 21.6.2008 Репутация: нет Всего: 3 |
Пробовал уже вычищать таким способом, по идее должно всё работать именно в случае последнего вашего сообщения, но не получается создание класса CSomeOther.
при создании экземпляра через new при компиляции вываливается " can not create, because IMyInterface::pA() = 0". Или не канифолить себе мозги, а заново описать метод pA(), который явно вызывает this->CMyInterface::pA()? Пока вкуриваю Inside the Com от Дэйла Роджерсона, он, в частности, предлагает создание экземпляра класса-агрегатора с суперсчётчиком ссылок, и перенаправлением всех методов вручную в этот m_ImyInterface. Неужели это единственный способ? Это сообщение отредактировал(а) Proxin - 21.9.2016, 23:35 |
|||
|
||||
xvr |
|
|||
Эксперт Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 8 Всего: 223 |
||||
|
||||
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: COM/DCOM/ActiveX/ATL/CORBA | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |