В заголовочных файлах да и в MaxsdkHelp указано что класс Interface является абстрактным. Но в примерах, прилагаемых к sdk, вызываются методы этого класса через указатель типа Interface: Код (Text): void AppDataTest::BeginEditParams(Interface *ip,IUtil *iu) { this->iu = iu; this->ip = ip; hPanel = ip->AddRollupPage( hInstance, MAKEINTRESOURCE(IDD_APPDATA_PANEL), AppDataTestDlgProc, GetString(IDS_RB_APPDATATEST), 0); } AppDataTest производный другого абстрактного класса: class AppDataTest : public UtilityObj Функция BeginEditParams является виртуальной пустой. Т.е. с одной стороны класс Interface абстрактный, с другой про класс Interface в sdk говорится что: Где реализованы пустые функции класса Interface ? Нет ли здесь противоречия с теорией?
нету. а где и как они реализованы, тебя не должно волновать, для того и ООП. указатель ip -- это указатель на инстанс какого-то класса, который и реализует пустые функции класса Interface.
В COM модели ip является адресом таблицы с адресами функций. Соответсвенно функция инициализации интерфейса заполняет эту таблицу и возвращает указатель на неё. Т.е. в данном случае реализуется вызов функции по её порядковому номеру (соответствие номера функции с её текстовым именем описано в заголовочных файлах, а в exe компилируется только её номер). В dll интерфейсах такой метод считается устаревшим и поддерживается только для совместимости, а в COM вот прижился за счёт запрета на любые изменения в уже опубликованном интерфейсе (можно только создать новый интерфейс с теми же чуть чуть изменёнными функциями .
[off] Всегда интересовало, почему там не рулит наследование? Зачем плодить кучку схожих ифейсов, наследованных от IUnknown или IDispatch, вместо того, чтобы наследоваться друг от друга? [/off]
В общих чертах основная идея в том, что если разрешить менять уже опубликованный интерфейс как заблагорассудится, то наплодится куча несовместимых версий и программы начнут обвально падать (законы Мерфи рулят Поэтому и ввели "правила игры" - прикладники могут наследовать внутри своей программы сколько угодно, а вот разработчики объектов с открыто публикуемым интерфейсом обязаны четко отделять новую версию от старой. В dll с экспортом функций по имени можно просто добавить к имени Ex и всем станет понятно, что это новая версия функции с возможно другими аргументами, а когда у функции есть только порядковый номер, то остаётся либо дико растягивать виртуальную таблицу забивая её однотипными функциями (что совсем уж не есть гуд и потому запрещено), либо полностью создавать новый интерфейс, который можно отличить от старого по GUID.
censored А ткнуть в мануал? Всё подряд учить не катит. Y_Mur То есть, нельзя даже опубликовать расширенный интерфейс старого, только совершенно новый?
В принципе часто новый интерфейс на самом деле расширенный старый, но M$ не рекомендует совместно использовать функции из разных интерфейсов посколько несмотря на внешнюю одинаковость их внутренняя реализация может конфликтовать со старой версией (а может и сработать, т.е. никаких гарантий). Из-за этого и обязали вводить новый GUID. Хотя если пишешь для себя, то никому ничего не должен и можно перекраивать и наследовать как удобнее )
По мануалу - достаточно популярно изложено в: Дональд Бокс. Сущность технологии СОМ. (не помню где взял, можно поискать по EssentialCOM_rus.chm) Еще есть перевод DirectX2 SDK http://hworld3000.chat.ru/files/directx.exe, интересно, что там надпись о непредсказуемости результатов смешивания интерфейсов следует сразу за примером, где это смешивание происходит )
Y_Mur Ага, спасибо. Книга есть, гляну на досуге. Но вопрос всё равно спорный, конечно. Хотя в свете поддержки всех и вся (бинарных реализаций ООП в языках) в СОМ становится понятнее.
Еще новый GUID при добавлении функции в неизменяемый интерфейс - подстраховка от случая когда разные программеры независимо друг от друга добавят (и опубликуют) новые функции, которые в итоге окажутся под одним номером (имена то только в *.h) А COM интерфейсы различающиеся по GUID придумали потому что dll, различающиеся только именем файла либо не исключают взаимного затирания, либо теряют своё основное достоинство - возможность свалить их в кучу и использовать совместно