-
Здравствуйте! Мне нужно сделать следующее. Имеется некий COM объект с известным интерфейсом. Я хочу создать свой COM объект, функциональность которого будет несколько изменена, то есть он должен выполнять определенные действия (методы интерфейса), заложенные в предке, но немного их изменять. Это аналог наследования классов в ООП. Как правильно такое сделать на COM?
-
> Имеется некий COM объект
Что значит имеется ? В смысле полные исх.тексты проекта сервера или только готовый исп.модуль сервера ?
-
готовый модуль
-
Проще будет ли реализовать собственный сервер с заданным интерфейсом и требуемой функциональностью.
Перехват интерфейсных вызовов - задача весьма нетривиальная.
-
модулей - наследников сервера должно быть много, и они должны выполнять общую часть функционала сервера предка и видоизменять ее (аналог полиморфизма) каждый по своему.
-
А по барабану сколько их будет.
-
>Проще будет ли реализовать собственный сервер с заданным интерфейсом и требуемой функциональностью. Мне нужно, чтоб я по 10 раз не переписывал общий код, находящийся в сервере, а использовал т о, что уже написано
-
> не переписывал общий код, находящийся в сервере
Ты ж сам сказал - исх.текста у тебя нет .. Что переписывать-то ?
-
Есть два варианта действий: агрегация и контейнирование.
Контейнирование - вещь, простая идеологически, но несколько муторная в реализации. Ваш объект становится клиентом того объекта, от которого вы хотите "унаследоваться". Вы экспортируете все те же интерфейсы, что и "предок", и реализуете их функции таким образом, что они просто вызывают аналогичные функции "предка". Работает такая штука всегда, но если методов много, приходится вручную писать "многа букф".
-
Агрегация сложнее для понимания, проще для реализации и не со всеми объектами будет работать. Ваш объект точно так же становится клиентом "предка", но свой метод QueryInterface вы реализуете таким образом, что, когда у вас запрашивают интерфейсы, реализуемые "предком", вы тупо возвращаете клиенту указатель на соответствующий интерфейс "предка", и клиент работает с ним напрямую.
-
Тут возникает одна проблема - получив такой интерфейс, клиент может вызвать у него методы, унаследованные IUnknown, и получится, что с точки зрения клиента эти методы работают по-разному в зависимости от того, какой из интерфейсов он использует - реализованный вами или тот, который получен вами от "предка", а стандартом COM такое не допускается. Чтобы этого не происходило, предок должен знать, что он агрегирован. Если вы посмотрите, например, функцию CoCreateInstance, то её второй параметр - pUnkOuter, указатель на внешний IUnknown. Создавая экземпляр "предка", вы должны будете через этот параметр передать ему указатель на свою реализацию IUnknown, и тогда "предок" будет знать, что он агрегирован, и функции IUnknown будет делегировать вашей реализации этого интерфейса. Тогда для внешнего клиента IUnknown будет всегда реализован одинаково при вызове из любого интерфейса. Правда, разработчик предка может и не захотеть возиться с делегированием IUnknown или по каким-то другим причинам запретить агрегацию. В этом случае при попытке создать объект с ненулевым pUnkOuter вы получите ошибку CLASS_E_NOAGGREGATION. Если у вас такая ситуация, значит, остаётся только контейнирование.
-
P.S. Извините, что разбил сообщение на несколько - глючный прокси у нас на работе не пропускает длинные HTTP-запросы.
-
>Григорьев Антон © Огромное спасибо. Я продумывал второй вариант - контейнирование, просто хотел разобраться, как такое делать правильно, может есть другие, стандартные средства.
>Сергей М. © (18.11.08 21:59) [7] >Ты ж сам сказал - исх.текста у тебя нет .. Что переписывать-то ? Часть из них буду писать я на дельфи, часть, возможно, кто-то другой, возможно даже на другом языке. Так что, в общем случае, я не имею возможности использовать исходный текст "предков" серверов COM.
-
Доброго времени суток. Делал через "контейнер", как указал Григорьев Антон. Все объекты уже несколько лет работают в разных проектах, глюков небыло.
|