M>> H>В дельфях тоже и что О другом речь... Ты походу не читатель нифига Вот Мамут говорит, а что мешало сделать интерфейсы в дельфях без наследования от IUnknown? Я говорю, да ничего не мешало, но для единообразия поведения с COM интерфейсами, обычным интерфейсам тоже пришлось бы обеспечивать механизм управления жизни реализующих объектов.
M>> Интерфейсы ничего не реализуют. Реализуют классы. Так, TInterfacedObject реализует класс iUnknown. Этого — достаточно, чтобы не засорять интерфейсы обязательным наличием COM-методов.
H>Мамут, ты непроходимо тут. Это выяснилось еще в первом споре и подтвердилось еще раз в этом. Я русским языком написал: "управления жизни реализующих объектов", ты продолжаешь мне рассказывать, что интерфейсы ничего не реализуют.
Про то, что интерфейсы что-то реализуют, постоянно говоришь ты и только ты (в частности, выделено выше).
Ну а так непроходимо туп ты.
1. В Delphi жизнь TObject'ов управляется совсем по другому, нежели жизнь COM-объектов
2. Почему-то тебе ничего не мешает наследоваться от TObject'ов и полагаться на чисто-дельфиские методы управления их жизнью
3. Но при этом ты продолжаешь быть уверен, что для объектов, реализующих интерфейсы просто таки необходим подход COM для управления их жизнью, несмотря на то, что:
4. Интерфейс является всего лишь, по сути, абстрактным классом и ничто не мешает иметь интерфейсы для взаимодействия с COM-ом (как это делается в том же C++), а в тех случаях, когда COM не нужен даром, не заставлять никого реализовывать COM-методы и получать в итоге COM-объекты.
Здравствуйте, Ikemefula, Вы писали:
I> I>> Гуид к интерфейсу не имеет никакого отношения.
I> H>К COM интерфейсу еще как имеет.
I> Поскольку интерфейсы наследуются от ИНТЕРФЕЙСА который УЖЕ имеет ГУИД, то никаких других гуидов добавлять не нужно — интерфейс уже будет COM-интерфейсом просто потому что наследуется от IUnknown.
Знаток, мля. Как же ты будешь получать интерфейс без GUID'а при отсутствии compiller magic (а коль скоро мы говорим о COM, то таки там ее нет)? Вот получил ты на вход IUnknown от другого модуля. Как ты получишь IMyIntf если не знаешь его GUID?
I> Гуид нужен для того, что бы запрашивать конкретный интерфейс.
Вот о том и речь, IMyIntf привести к IUnknown можно, а вот IUnknown к IMyIntf нельзя.
I> А для самого интерфейса ГУИД не нужен, потому что он уже есть.
Учи мат часть, знаток. Каждый интерфейс в COM должен обладать собственным уникальным GUID. GUID не наследуется. Запросив GUID от IUnknown ты получаешь только IUnknnown.
I> Это вовсе не мало, кстати говоря. Удивишься, но с COM можно делать много всякой всячины без назначения специального гуида на интерфейс — чисто на одном IUnknown.
Ну да. Без GUID'а можно счетчиком сЦылок рулить
I> Интерфейс для компилера это всего лишь бинарный стандарт для вызова методов.
Спасибо К.О.
I> Вот такие тонкости вы, программисты на дельфи, постоянно упускаете из виду.
Здравствуйте, Ikemefula, Вы писали:
I> M>> Это грязный хак для работы с COM-ом. Не знаю, как сейчас, но в Delphi не было не-COM интерфейсов.
I> H>Ты еще не устал эту глупость повторять?
I> А чем отличается COM от не-COM интерфейса ?
I> В правильном компилере, правильно, практически ничем.
Много чем может отличаться. Я тебе больше скажу, понятие интерфейса вообще мало соотносится с конкректным компилятором.
I> Но ты, по Дельфям специалист, что поведаешь нам, в Дельфях ошибка или Дельфи плохо знаешь ты ?
Здравствуйте, Mamut, Вы писали:
M> M>> Это грязный хак для работы с COM-ом. Не знаю, как сейчас, но в Delphi не было не-COM интерфейсов.
M> H>Ты еще не устал эту глупость повторять?
M> Покажи мне не-COM интерфейс в дельфи. Такой, который бы не требовал реализации IUnknown и т.п.
А при чем тут IUnknown? Да, в дельфях все интерфейсы наследуются от IUnknown (если быть точным — от IInterface, что суть тоже самое). Это нужно для совместимости с COM. При этом, далеко не каждый интерфейс будет являться COM-интерфейсом.
Здравствуйте, hattab, Вы писали:
MM>> Слушай, у тебя, что не ответ Мамуту, то попытка оскорбить. Может сбавишь обороты, а? H>Что-то ты к Мамуту не лезешь, когда он Шеридана поливает.
им можно. я так вообще серьёзно думаю, что они в жаббере договариваются кто кого где и как ссаными тряпками гонять будет.
Здравствуйте, Mamut, Вы писали:
M> H>Совместимость с COM + управление временем жизни. Я ведь написал уже.
M> Стоп. То у тебя интерфейсы совместимы с COM, то они не совместимы. Ты уже определись
Я что, непонятно написал? IUnknown нужен для совместимости с COM, но это не значит, что любой интерфейс будет совместим с COM.
M> M>> Ничего нем элегантного нет. TObject не управляет временем жизни, и как-то без этого обходятся, а для интерфейсов ВНЕЗАПНО понадобилось управление?
M> H>Было бы лучше, если бы для COM-интерфейсов время жизни было управляемым, а для остальных нет? Зачем плодить сущности без надобности?
M> Это не плождение сущностей без надобности. Интерфейс — это вообще, по сути, абстрактный класс, контракт на исполнение. IInterface обязует всю наследующую цепочку реализовывать определенный контракт. Который даром не сдался для не-COM сущностей. Который ларом не сдался для сущностей, которые не обязаны быть COM-совместимыми.
Ты какую-то формулировку берешь за догму, и говоришь, что в дельфях оно не так, а значит все плохо? Не смеши меня больше.
M> M>> H>Можно ли было, для поддержки интерфейсов, обойтись без IUnknown вообще? Разумеется. Но в таком случае пришлось бы разделять понятия интерфейса в рамках языка и интерфейса для COM (плюс обеспечивать механизм управления временем жизни). Какой в этом смысл? Никакого. Лишние сущности.
M> M>> Лишние сущности — это насаждение QueryInterface, AddRef и Release повсюду, где они и не нужны. Нужен COM-интерфейс? Отнаследуйся себе от IInterface/IUnknown — и вперед.
M> H>Нафиг нужно это разграничение (COM/не COM), когда для поддержки обоих видов требуется идентичная функциональность?
M> С какоко перепугу она вдруг требуется?
Для единообразия. Еще раз:
M> H>Было бы лучше, если бы для COM-интерфейсов время жизни было управляемым, а для остальных нет?
M> ТО, что так сделали в Delphi — ну так это проблемы Delphi, что они изначально все на COM завязали.
Интерфейсы там появились благодаря COM, это несомненно. И именно благодаря одному из ключевых моментов COM (QueryInterface) достигается офигительный профит при их использовании. Без аналогичного механизма поддержка интерфейсов не более чем пшик.
M> M>> Ты не поверишь. Это возможно в любом языке с ООП. Только в нормальных языках никто не запихивает ненужные методы тебе в глотку, как это делает delphi.
M> H>Я не знаю, чего тебе дельфя в глотку запихивала... Назови пару языков работающих в нативе (ключевой момент), которые имеют реализацию интерфейсов отличную от реализации COM-интерфейсов. При этом обеспечивают бесшовную интероперабельность с этим самым COM. Или даже не с COM, а с интерфейсами своих же нативных модулей от другого вендора.
M> Абстрактные классы в С++ — это и есть интерфейсы. И в С++ есть бесшовная связка с COM. Не путай мух и котлет. Мухи отдельно, котлеты отдельно.
M> Нативный-ненативный значения не имеет. Интерфейсы вообще к COM'у никакого отношения не имеют.
Я в данном случае не о COM говорю. И нативность тут имеет самое непосредственное значение и вот почему. Если на управляемых платформах все обвешано метой и царит "полное взаимопонимание" между взаимодействующими сущностями т.к. работают они в однородной среде, то в нативе всего этого нет. Без того самого IUnknown (или его аналога) работа с интерфейсами в нативе была бы невозможна в принципе. Следует понимать, что дельфя это все же разработка нативных приложений и следовательно принимаемые решения основываются на данном факте. Т.ч. эти ваши сопли о нормальных языках тут не катят.
M> H>А в чем принципиальный затык наследования от TInterfacedObject, вместо TObject, кроме маразматического эстетства?
M> В том, что никому даром не уперлись QueryInterface, AddRef и Release, кроме как в случае работы с COM'ом. И обязательная совместимость с COM'ом тоже даром не упала. Нужна совместимость с COM'ом — вперед, наследуйся от IINterface/TInterfacedObject и радуйся жизни, как это во всех нормальных языках делают.
Еще раз: IUnknown это не работа с COM. Это базовый элемент COM, да, но не более.
M>> H>Совместимость с COM + управление временем жизни. Я ведь написал уже. M>> Стоп. То у тебя интерфейсы совместимы с COM, то они не совместимы. Ты уже определись H>Я что, непонятно написал? IUnknown нужен для совместимости с COM, но это не значит, что любой интерфейс будет совместим с COM.
Итак. Если они несовместимы с COM, зачем там QueryInterface, AddRef и Release? Просто так, чтобы были?
M>> M>> Ничего нем элегантного нет. TObject не управляет временем жизни, и как-то без этого обходятся, а для интерфейсов ВНЕЗАПНО понадобилось управление?
M>> H>Было бы лучше, если бы для COM-интерфейсов время жизни было управляемым, а для остальных нет? Зачем плодить сущности без надобности?
M>> Это не плождение сущностей без надобности. Интерфейс — это вообще, по сути, абстрактный класс, контракт на исполнение. IInterface обязует всю наследующую цепочку реализовывать определенный контракт. Который даром не сдался для не-COM сущностей. Который ларом не сдался для сущностей, которые не обязаны быть COM-совместимыми.
H>Ты какую-то формулировку берешь за догму, и говоришь, что в дельфях оно не так, а значит все плохо? Не смеши меня больше.
Это не догма, это нормально определение интерфейса. И да, в дельфи интерфейсы появились только для работы с COM'ом. То, что их используют не по назначению, говоит только о недальновидности разработчиков самого Delphi.
M>> M>> H>Можно ли было, для поддержки интерфейсов, обойтись без IUnknown вообще? Разумеется. Но в таком случае пришлось бы разделять понятия интерфейса в рамках языка и интерфейса для COM (плюс обеспечивать механизм управления временем жизни). Какой в этом смысл? Никакого. Лишние сущности.
M>> M>> Лишние сущности — это насаждение QueryInterface, AddRef и Release повсюду, где они и не нужны. Нужен COM-интерфейс? Отнаследуйся себе от IInterface/IUnknown — и вперед.
M>> H>Нафиг нужно это разграничение (COM/не COM), когда для поддержки обоих видов требуется идентичная функциональность?
M>> С какоко перепугу она вдруг требуется?
H>Для единообразия. Еще раз: H>
M> H>Было бы лучше, если бы для COM-интерфейсов время жизни было управляемым, а для остальных нет?
Интерфейс вообще не является управляемым-неуправляемым. Интерфейс является контрактом на поведение. Он сам по себе не способен быть управляемым-неуправляемым.
Нужен ли QueryInterface для управляемости? Даром не нужен.
Нужны ли AddRef и Release для управляемости? Только в рамках COM'а. В самом Delphi другой механизм управления жизнью объектами.
M>> ТО, что так сделали в Delphi — ну так это проблемы Delphi, что они изначально все на COM завязали.
H>Интерфейсы там появились благодаря COM, это несомненно. И именно благодаря одному из ключевых моментов COM (QueryInterface) достигается офигительный профит при их использовании. Без аналогичного механизма поддержка интерфейсов не более чем пшик.
Никакого профита там нет. То, что ты имеешь реализованный в TInterfacedObject счетчик ссылок никак не влияет на миллион других объектов, наследованных от TObject. но это почему-то тебя не удивляет. А вот возможность иметь мухи и котлеты отдельно ты называешь введением доп. сущностей
M>> M>> Ты не поверишь. Это возможно в любом языке с ООП. Только в нормальных языках никто не запихивает ненужные методы тебе в глотку, как это делает delphi.
M>> H>Я не знаю, чего тебе дельфя в глотку запихивала... Назови пару языков работающих в нативе (ключевой момент), которые имеют реализацию интерфейсов отличную от реализации COM-интерфейсов. При этом обеспечивают бесшовную интероперабельность с этим самым COM. Или даже не с COM, а с интерфейсами своих же нативных модулей от другого вендора.
M>> Абстрактные классы в С++ — это и есть интерфейсы. И в С++ есть бесшовная связка с COM. Не путай мух и котлет. Мухи отдельно, котлеты отдельно.
M>> Нативный-ненативный значения не имеет. Интерфейсы вообще к COM'у никакого отношения не имеют.
H>Я в данном случае не о COM говорю. И нативность тут имеет самое непосредственное значение и вот почему. Если на управляемых платформах все обвешано метой и царит "полное взаимопонимание" между взаимодействующими сущностями т.к. работают они в однородной среде, то в нативе всего этого нет. Без того самого IUnknown (или его аналога) работа с интерфейсами в нативе была бы невозможна в принципе.
Да ты что, неужели
Интерфейс — это абстрактный класс. Всё. Ничем другим interface, по сути, не является. Даже в Delphi. Вон, С++ работает с COM-интерфейсами и ничего, все нормально.
Как и в Java, интерфейсы появились в Delphi для обхода запрета на множественное наследование. Только в Delphi интерфейсы гвоздями прибили к COM'у. Зачем? Потому что в COM'е есть множественное наследование, а разработчики Delphi не придумали ничего более умного, чем прибить к COM'у всю концепцию интерфейсов. Хотя к COM'у интерфейсы не имеют никакого отношения.
H>Следует понимать, что дельфя это все же разработка нативных приложений и следовательно принимаемые решения основываются на данном факте. Т.ч. эти ваши сопли о нормальных языках тут не катят.
M>> H>А в чем принципиальный затык наследования от TInterfacedObject, вместо TObject, кроме маразматического эстетства?
M>> В том, что никому даром не уперлись QueryInterface, AddRef и Release, кроме как в случае работы с COM'ом. И обязательная совместимость с COM'ом тоже даром не упала. Нужна совместимость с COM'ом — вперед, наследуйся от IINterface/TInterfacedObject и радуйся жизни, как это во всех нормальных языках делают.
H>Еще раз: IUnknown это не работа с COM. Это базовый элемент COM, да, но не более.
Который даром не нужен, если нам COM не нужен.
Объясняю в терминах Delphi. Предположим, в interface не заложена привязка ни к IInterface ни к IUnknown:
IMyInterface = Interface()
function GetMyProperty : Boolean;
property myProperty : Boolean read GetMyProperty;
end;
// TMyСlass по сути является TObject'ом, мы указали ему контракт
// он обязан реализовать метод GetMyProperty
TMyClass = class(TObject, IMyInterface)
...
// реализуем IUnknown, как в любом человеческом языке
IUnnknown = Interface()
function QueryInterface : Interface;
function AddRef : Ref;
function Release : Boolean;
end;
// TInterfacedObject обязан реализовать методы из интерфейса
TInterfacedObject = class(TObject, IUnknown)
// Пишем класс, в котором нам нужны COM-методы. У нужны они нам только тут,
// а не в TMyClass выше
TMyCOMClass = class(TInterfacedObject, IMyInterface)
Мир внезапно перевернулся? Нет. Исчезла гвоздями прибитая привязанность к COM'у? Да, исчезла.
Здравствуйте, Mamut, Вы писали:
M> M>> M>> В этом разрезе все интереснее, как они будут реализовывать кроссплатформенный Дельфи. Забъют все заглушками, наверняка.
M> M>> H>Какие еще заглушки, клоВун Мамут, спасибо тебе, я давно так не ржал Хоть и грешно над убогими...
M> M>> За неимением в Линуксах COM-а, убогенький ты мой
M> H> Ой, Мамут... ты такой Мамут Снова COM вспомнил Пацталом
M> Твои слова:
M>
M> IUnknown нужен для совместимости с COM
M> COM-совместимость никто не отрицал
M> в дельфях все интерфейсы наследуются от IUnknown (если быть точным — от IInterface, что суть тоже самое). Это нужно для совместимости с COM.
M> IUnknown обязателен в дельфях для гармоничного встраивания в инфраструктуру COM
Ну мои слова, и что? Причем тут твои заглушки для Линукс? Иди уже с матчастью ознакомься наконец
M> Более того:
M>
M> Без того самого IUnknown (или его аналога) работа с интерфейсами в нативе была бы невозможна в принципе
M> На что тебе уже не раз было замечено, что это — ложь.
M> Дальше — ликбез: http://ru.wikipedia.org/wiki/Интерфейс_(объектно-ориентированное_программирование)
Ну что я могу сказать... Мамут ты идиот Вот об этом
M>Это грязный хак для работы с COM-ом. Не знаю, как сейчас, но в Delphi не было не-COM интерфейсов.
По-моему, это вполне себе чистый хак для работы с COM-ом.
Такой реализацией Хейльсберг дал возможность использовать ком-объекты в Дельфи без ручного подсчёта ссылок и пользования QueryInterface.
Какие у него были варианты?
1. Сделать два типа интерфейсов: унаследованные от IUnknown и все остальные. Компилятор отслеживает поведение IUnknown-based, автоматически подсчитывая ссылки и преобразуя приведение типов к QueryInterface. Для "обычных" интерфейсов он этого не делает.
Такая политика может приводить к трудноуловимым глюкам в тех случаях, когда класс реализует сразу несколько интерфейсов. Получается, разные ссылки на этот объект будут вести себя по-разному. Вот мы сохраняем ссылку на "обычный" интерфейс. Как знать, вдруг за ней скрывается объект с поддержкой IUnknown? Проверять ли это и подсчитывать ли ссылки?
Как делать приведения к интерфейсу? Вот мы приводим "обычный" интерфейс к IUnknown-based. Возможно, он реализован через агрегацию, которая встроена в язык. Стало быть, обычный каст даст неверный результат — нужно лезть в QueryInterface.
В общем, что-то не клеится такая автоматика. Получаем переусложнение на ровном месте, и паранойю компилятора во всех местах использования интерфейсов типа "а вдруг там сзади COM?"
2. Сделать ровно один тип интерфейсов. IUnknown — такой же, как и все; никакой магии нет. Получается, для банальной работы с ком-объектами нужно везде руками писать AddRef/Release/QueryInterface. Постоянно помнить о том, что приведение типов через каст может работать-работать, а потом вдруг перестать — если реализация данного конкретного интерфейса изменилась на агрегацию.
Работать — работает, но как-то грубо по отношению к девелоперам. Это примерно то же, что и поддержка COM в чистом C: реализовать можно, но помощи от компилятора нет.
3. Принудительно сделать все интерфейсы ком-совместимыми. В итоге за счёт весьма небольшой цены (фактически, припиливания 4х байт к каждому объекту, реализующему хоть какой-то интерфейс) имеем очень хорошую поддержку как разработки COM-классов, так и использования; при этом компилятор достаточно прямолинеен и предсказуем.
На всякий случай напомню, что дедушка Хейльсберг знаменит как раз тем, что он специализируется на написании кода для пользы, а не для красоты. Его задачей была не абстрактная реализация красивой идеи интерфейсов, а облегчение жизни виндовс-девелоперам. Ну как в C# 3.0 была задача "сделать лёгким взаимодействие с СУБД", так и в Дельфи ставилась задача "сделать лёгким взаимодействие с COM". Тогда это было более важным.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, hattab, Вы писали:
H>Много чем может отличаться. Я тебе больше скажу, понятие интерфейса вообще мало соотносится с конкректным компилятором.
Потому и разницы быть не должно. А если она есть — компилер кривой.
I>> Но ты, по Дельфям специалист, что поведаешь нам, в Дельфях ошибка или Дельфи плохо знаешь ты ? H>У дельфей все в порядке, не беспокойся.
M>> M>> Это грязный хак для работы с COM-ом. Не знаю, как сейчас, но в Delphi не было не-COM интерфейсов.
M>> H>Ты еще не устал эту глупость повторять?
M>> Покажи мне не-COM интерфейс в дельфи. Такой, который бы не требовал реализации IUnknown и т.п.
H>А при чем тут IUnknown? Да, в дельфях все интерфейсы наследуются от IUnknown (если быть точным — от IInterface, что суть тоже самое). Это нужно для совместимости с COM. При этом, далеко не каждый интерфейс будет являться COM-интерфейсом.
Выделенное противоречит друг другу.
Вопрос: можно ли в дельфях сделать интерфейс, не наследующися от IUnknown? Зачем мне обязательная зависимость/совместимость с COM'ом?
пример:
interface Bicycle {
void changeCadence(int newValue); // wheel revolutions per minutevoid changeGear(int newValue);
void speedUp(int increment);
void applyBrakes(int decrement);
}
class ACMEBicycle implements Bicycle {
// remainder of this class implemented as before
}
Вот нахрена мне тут IUknown? А вот он мне даром не нужен. Но нет, в Delphi я буду обязан реализовать все методы IUnknown'а или он автоматом будет реализован Delphi. Нахрена?
Здравствуйте, Ikemefula, Вы писали:
I> M>> Покажи мне не-COM интерфейс в дельфи. Такой, который бы не требовал реализации IUnknown и т.п.
I> H>А при чем тут IUnknown? Да, в дельфях все интерфейсы наследуются от IUnknown (если быть точным — от IInterface, что суть тоже самое). Это нужно для совместимости с COM. При этом, далеко не каждый интерфейс будет являться COM-интерфейсом.
I> "Но ты, по Дельфи специалист, что поведаешь нам, разница в чём или Дельфи плохо знаешь ты ?" @
Чтоб сильно тебя не раскармливать... В дельфях можно объявить интерфейс без GUID'а.
Здравствуйте, Mamut, Вы писали:
M> M>> M>> Это грязный хак для работы с COM-ом. Не знаю, как сейчас, но в Delphi не было не-COM интерфейсов.
M> M>> H>Ты еще не устал эту глупость повторять?
M> M>> Покажи мне не-COM интерфейс в дельфи. Такой, который бы не требовал реализации IUnknown и т.п.
M> H>А при чем тут IUnknown? Да, в дельфях все интерфейсы наследуются от IUnknown (если быть точным — от IInterface, что суть тоже самое). Это нужно для совместимости с COM. При этом, далеко не каждый интерфейс будет являться COM-интерфейсом.
M> Выделенное противоречит друг другу.
Нет там никакого противоречия.
M> Вопрос: можно ли в дельфях сделать интерфейс, не наследующися от IUnknown?
Интерфейс в дельфях всегда наследуется от IInterface.
M> Зачем мне обязательная зависимость/совместимость с COM'ом?
Наличие IUnknown не делает интерфейс COM-совместимым. Сурпрайз?
M> пример:
M>
M> interface Bicycle {
M> void changeCadence(int newValue); // wheel revolutions per minute
M> void changeGear(int newValue);
M> void speedUp(int increment);
M> void applyBrakes(int decrement);
M> }
M> class ACMEBicycle implements Bicycle {
M> // remainder of this class implemented as before
M> }
M>
M> Вот нахрена мне тут IUknown? А вот он мне даром не нужен. Но нет, в Delphi я буду обязан реализовать все методы IUnknown'а или он автоматом будет реализован Delphi. Нахрена?
IUnknown обязателен в дельфях для гармоничного встраивания в инфраструктуру COM и вместе с тем это элегантное решение проблемы управляемого времени жизни. Можно ли было, для поддержки интерфейсов, обойтись без IUnknown вообще? Разумеется. Но в таком случае пришлось бы разделять понятия интерфейса в рамках языка и интерфейса для COM (плюс обеспечивать механизм управления временем жизни). Какой в этом смысл? Никакого. Лишние сущности. Ситуация с интерфейсами в дельфях совершенно нормальна. Можно применять COM-совместимые интерфейсы, а можно и такие которые в рамках COM использованы быть не могут (но при этом, двух разных понятий об интерфейсах не существует). Ты не обязан самостоятельно реализовывать IUnknown, достаточно унаследоваться от класса его реализующего.
Здравствуйте, Ikemefula, Вы писали:
I> I>> "Но ты, по Дельфи специалист, что поведаешь нам, разница в чём или Дельфи плохо знаешь ты ?" @
I> H>Чтоб сильно тебя не раскармливать... В дельфях можно объявить интерфейс без GUID'а.
I> Гуид к интерфейсу не имеет никакого отношения.
Здравствуйте, hattab, Вы писали:
I>> Гуид к интерфейсу не имеет никакого отношения.
H>К COM интерфейсу еще как имеет.
Поскольку интерфейсы наследуются от ИНТЕРФЕЙСА который УЖЕ имеет ГУИД, то никаких других гуидов добавлять не нужно — интерфейс уже будет COM-интерфейсом просто потому что наследуется от IUnknown.
Гуид нужен для того, что бы запрашивать конкретный интерфейс. А для самого интерфейса ГУИД не нужен, потому что он уже есть.
Это вовсе не мало, кстати говоря. Удивишься, но с COM можно делать много всякой всячины без назначения специального гуида на интерфейс — чисто на одном IUnknown.
Интерфейс для компилера это всего лишь бинарный стандарт для вызова методов.
Вот такие тонкости вы, программисты на дельфи, постоянно упускаете из виду.
Here is the bare minimum required for a COM interface:
class CMyClass : public IUnknown
{
private:
ULONG m_cRef; // COM reference countpublic:
STDMETHODIMP QueryInterface(REFIID riid, void** ppvObject)
{
IUnknown *punk = nullptr;
if (riid == IID_IUnknown)
punk = static_cast<IUnknown*>(this);
// TODO: List other implemented interfaces in a similar manner.
*ppv = punk;
if (!punk)
return E_NOINTERFACE;
punk->AddRef();
return S_OK;
}
STDMETHODIMP_(ULONG) AddRef()
{
return ++m_cRef;
}
STDMETHODIMP_(ULONG) Release()
{
ULONG cRef = --m_cRef;
if (cRef == 0)
delete this;
return cRef;
}
};
Это — TInterfacedObject из Delphi, который это и реализует.
Любой интерфейс в Delphi является COM-интерфейсом (так как обязывает реализовывать COM-минимум).
Любая реализация любого интерфейса в Delphi является COM-классом/объектом (так как обязана реализовывать COM-минимум).
M>>Любой интерфейс в Delphi является COM-интерфейсом (так как обязывает реализовывать COM-минимум). M>>Любая реализация любого интерфейса в Delphi является COM-классом/объектом (так как обязана реализовывать COM-минимум).
K>COM-совместимым или COM-подобным? Т.к. у меня строгая ассоциация: COM интерфейс должен иметь свой guid; иначе, это просто интерфейс реализующий IUnk., причем реализовать методы AddRef, Release — можно по своему, вопреки СОМ канону =)
Вообще-то, COM-совместимым. То, что он реализует только IUnknown, не делает его не-COM'ом Ну, захотелось человеку только IUnknown реализовать
А AddRef, Release можно и по-своему реализовать, например просто возвращать всегда 0 Ну, получится плохой COM-объект Но реализовывать их все равно придется.
>>>интерфейсы
PD>>Ну это как сказать. Поинтересуйся, как в Delphi c COM работают.
M>Это грязный хак для работы с COM-ом. Не знаю, как сейчас, но в Delphi не было не-COM интерфейсов.
что тебе нужно? написать в делфях CORBA-интерфейс?
Здравствуйте, Mamut, Вы писали:
M>Это грязный хак для работы с COM-ом. Не знаю, как сейчас, но в Delphi не было не-COM интерфейсов.
Вот что мне нравилось по части интерфейсов в Delphi, так это следующая фича.
PD>>>Ну это как сказать. Поинтересуйся, как в Delphi c COM работают.
M>>Это грязный хак для работы с COM-ом. Не знаю, как сейчас, но в Delphi не было не-COM интерфейсов.
MA>что тебе нужно? написать в делфях CORBA-интерфейс?
К.О. сообщает, что интерфейсы не ограничиваются межпрограммными коммуникациями.
Здравствуйте, mister-AK, Вы писали:
AK> M>Это грязный хак для работы с COM-ом. Не знаю, как сейчас, но в Delphi не было не-COM интерфейсов.
AK> что тебе нужно? написать в делфях CORBA-интерфейс?
Да ничего ему не нужно, у него просто зудит в заднем проходе. Неосиляторы, они такие...
H>Несмотря на то, что IMyIntf наследуется от IInterface (IUnknown), сам он не является COM-интерфейсом т.к. не имеет собственного GUID'а.
IMyIntf обязывает реализовывать COM-методы. В результате каждый полученный объект будет COM-объектом. Как называется интерфейс, при реализации которого получается только COM-объект, и никакого другого? COM-интерфейс.
Если бы в Delphi (как в нормальных языках) при реализации интерфейса можно было получить не COM-объект, то тогда были бы в нем не COM-интерфейсы.
На этом фоне интересны потуги embarcadero(или как их там) сделать кроссплатформенный Delphi. Им придется или интерфейсы сделать человеческими или тупо делать заглушки.
Здравствуйте, Mamut, Вы писали:
M> H>В дельфях тоже и что О другом речь... Ты походу не читатель нифига Вот Мамут говорит, а что мешало сделать интерфейсы в дельфях без наследования от IUnknown? Я говорю, да ничего не мешало, но для единообразия поведения с COM интерфейсами, обычным интерфейсам тоже пришлось бы обеспечивать механизм управления жизни реализующих объектов.
M> Интерфейсы ничего не реализуют. Реализуют классы. Так, TInterfacedObject реализует класс iUnknown. Этого — достаточно, чтобы не засорять интерфейсы обязательным наличием COM-методов.
Мамут, ты непроходимо тут. Это выяснилось еще в первом споре и подтвердилось еще раз в этом. Я русским языком написал: "управления жизни реализующих объектов", ты продолжаешь мне рассказывать, что интерфейсы ничего не реализуют. У вас, в Молдове, русский как-то по другому понимают, или это только ты уникум такой?
Здравствуйте, Mamut, Вы писали:
M>Вопрос: можно ли в дельфях сделать интерфейс, не наследующися от IUnknown? Зачем мне обязательная зависимость/совместимость с COM'ом?
Вопрос из серии: можно ли в Delphi создать объект, не наследуемый от TObject. Зачем эта обязательная совместимость? Зачем все эти методы, которые в нем имеются?
На самом деле все намного проще. Это особенность реализации. Имеет смысл говорить о том, какой оверхид будет при использовании этих особенностей. Говорить о том, можно ли реализовать CORBA-интерфейс. Какой процент задач можно решить при помощи этой концепции.
M>>1. В Delphi жизнь TObject'ов управляется совсем по другому, нежели жизнь COM-объектов
_>В Delphi жизнь TObject'ов никак не управляется. В общем случае действует простое правило — кто создал объект должен его и уничтожить, или поручить уничтожение другому объекту. Delphi сама никогда не уничтожает объекты — в Delphi нет дефолтных деструкторов.
Еще как управляется. Достаточно взять GUI-классы — и вперед. Какой-нибудб TTree спокойно себе управляет жизнью своих TTreeItem'ов. Благодаря чему начинаются глюки, если попытаться туда запихнуть что-либо, реализующее интерфейсы.
M>>несмотря на то, что: M>>4. Интерфейс является всего лишь, по сути, абстрактным классом и ничто не мешает иметь интерфейсы для взаимодействия с COM-ом (как это делается в том же C++), а в тех случаях, когда COM не нужен даром, не заставлять никого реализовывать COM-методы и получать в итоге COM-объекты.
_>Это в С++. Интерфейсы Delphi не являются абстрактными классами. Если тебе нужен абстрактный класс — сделай абстрактный класс, никто не мешает. Безо всяких IUnknown.
Дело в том, что в Delphi нет множественного наследования, и интерфейсы — это единственный способ задать разное поведение обхекту. Тольков от облом — это поведение будет гвоздями прибито к DOM'у.
Здравствуйте, hattab, Вы писали:
H>Блин, а если не дергать фразы из контекста? Там же целый абзац, поясняющий смысл... Представь себе, что и в ООПнутом паскале работа с интерфейсами без IUnknown и аналогичного механизма возможна (и она, таки, прямо сейчас используется). Но я же говорю не только о конкретном, отдельно взятом, паскале или си. Я говорю о нативной среде. Там где работает compiler magic (или используется мета из управляемых сред) нафиг не нужны ни какие QueryInterface, другое дело, когда речь идет о нативной среде вообще (и как я уже сказал, принимаемые решения авторами языка не могли не учитывать сего факта). И тут без механизма аналогичного IUnknown не обойтись.
Ок, тогда расскажи нам, что ты подразумеваешь под нативностью среды? Что в конце концов мешает компилятору просто генерить методы IUnknown также, как он добавляет наследование от TObject?
Здравствуйте, Alexander G, Вы писали:
AG>Не вижу разницы между наследованием от TObject для объектов и наследованием от IInterface для интерфейсов
Есть нюанс. Наследование от TObject не обязывает меня реализовывать методы, которые мне не нужны, чего не скажешь в случае наследования от IInterface.
Здравствуйте, Mamut, Вы писали:
M> Угу, скорее при реализации интерфейсов, они COM не просто гвоздями прибили, но еще и привинтили болтами М9.
M> В этом разрезе все интереснее, как они будут реализовывать кроссплатформенный Дельфи. Забъют все заглушками, наверняка.
Какие еще заглушки, клоВун Мамут, спасибо тебе, я давно так не ржал Хоть и грешно над убогими...
Здравствуйте, hattab, Вы писали:
H>Какие еще заглушки, клоВун Мамут, спасибо тебе, я давно так не ржал Хоть и грешно над убогими...
Вместо того, чтобы ржать попусту да переходить на личности, ответь лучше на это
M>>Потому что интерфейсы != COM. Ликбез: http://ru.wikipedia.org/wiki/Интерфейс_(объектно-ориентированное_программирование)
M>Интерфейс это семантическая и синтаксическая конструкция в коде программы, используемая для специфицирования услуг, предоставляемых классом или компонентом.
M>В каком месте интерфейсы Delphi не удовлетворяют этому определению?
Определению удовлетворяют, я против этого и не выступаю У меня вызывает недоумение необходимость прибивать их гвоздями к COM'у.
Более того, у меня вызывает недоумение уверенность хаттаба, что без COM'овских методов с интерфейсами в нативе нельзя работать («в нативной среде работа с интерфейсами без аналога IUnknown является не более чем пшиком») что является в лучшем случае бредом, в худшем — идиотизмом.
Здравствуйте, hattab, Вы писали:
H>Вот-вот, я и говорю, нифига ты не понимаешь... QueryInterface страшная сила, если начать думать, а не повторять зазубренные формулировки.
Слушай, у тебя, что не ответ Мамуту, то попытка оскорбить. Может сбавишь обороты, а?
Здравствуйте, MxMsk, Вы писали:
H>>Вот-вот, я и говорю, нифига ты не понимаешь... QueryInterface страшная сила, если начать думать, а не повторять зазубренные формулировки. MM>Слушай, у тебя, что не ответ Мамуту, то попытка оскорбить. Может сбавишь обороты, а?
Он просто не может найти нужный аргумент ни на хоботе, ни на хабре, потому повторяет чьи то фразы.
Здравствуйте, Ikemefula, Вы писали:
I> MM>Слушай, у тебя, что не ответ Мамуту, то попытка оскорбить. Может сбавишь обороты, а?
I> Он просто не может найти нужный аргумент ни на хоботе, ни на хабре, потому повторяет чьи то фразы.
M>> С чего это вдруг они будут являться пшиком? Интерфейсы — не более, чем реализация множественного наследования в языках, где множественного наследования нет (например, в Delphi). При чем тут COM'овские методы?
H>Вот-вот, я и говорю, нифига ты не понимаешь... QueryInterface страшная сила, если начать думать, а не повторять зазубренные формулировки.
При чем тут QueryInterface к множественному наследованию? Правильно, оно к нему вообще никакого отношения не имеет. Оно имеет отношение только к COM'у
Здравствуйте, hattab, Вы писали:
H>С чего это вдруг? В VCL полно мест где используются интерфейсы, и интеропом с COM там даже не пахнет.
На тот момент, когда я последний раз всерьез что то писал на Дельфи (лет 8 назад) таких мест практически не было. Сами интерфейсы там присутствовали уже лет 5 на тот момент.
Здравствуйте, Mamut, Вы писали:
PD>>Ну это как сказать. Поинтересуйся, как в Delphi c COM работают.
M>Это грязный хак для работы с COM-ом. Не знаю, как сейчас, но в Delphi не было не-COM интерфейсов.
Он в очередной раз потерял контекст, речь была про его любиый Turbo Pascal.
В ём не было интерфейсов ибо это досовская дрянь максимум на 16 бит и толко в реальном режиме процессора.
Здравствуйте, Mamut, Вы писали:
M> >>интерфейсы
M> PD>Ну это как сказать. Поинтересуйся, как в Delphi c COM работают.
M> Это грязный хак для работы с COM-ом. Не знаю, как сейчас, но в Delphi не было не-COM интерфейсов.
Здравствуйте, hattab, Вы писали:
M>> Это грязный хак для работы с COM-ом. Не знаю, как сейчас, но в Delphi не было не-COM интерфейсов.
H>Ты еще не устал эту глупость повторять?
А чем отличается COM от не-COM интерфейса ?
В правильном компилере, правильно, практически ничем.
Но ты, по Дельфям специалист, что поведаешь нам, в Дельфях ошибка или Дельфи плохо знаешь ты ?
Здравствуйте, Ikemefula, Вы писали:
I> H>Много чем может отличаться. Я тебе больше скажу, понятие интерфейса вообще мало соотносится с конкректным компилятором.
I> Потому и разницы быть не должно. А если она есть — компилер кривой.
Еще раз выделенное прочитай.
I> I>> Но ты, по Дельфям специалист, что поведаешь нам, в Дельфях ошибка или Дельфи плохо знаешь ты ?
I> H>У дельфей все в порядке, не беспокойся.
I> Намёк понял я
Здравствуйте, hattab, Вы писали:
I>> H>Много чем может отличаться. Я тебе больше скажу, понятие интерфейса вообще мало соотносится с конкректным компилятором.
I>> Потому и разницы быть не должно. А если она есть — компилер кривой.
H>Еще раз выделенное прочитай.
M>> >>интерфейсы
M>> PD>Ну это как сказать. Поинтересуйся, как в Delphi c COM работают.
M>> Это грязный хак для работы с COM-ом. Не знаю, как сейчас, но в Delphi не было не-COM интерфейсов.
H>Ты еще не устал эту глупость повторять?
Покажи мне не-COM интерфейс в дельфи. Такой, который бы не требовал реализации IUnknown и т.п.
Здравствуйте, hattab, Вы писали:
M>> Покажи мне не-COM интерфейс в дельфи. Такой, который бы не требовал реализации IUnknown и т.п.
H>А при чем тут IUnknown? Да, в дельфях все интерфейсы наследуются от IUnknown (если быть точным — от IInterface, что суть тоже самое). Это нужно для совместимости с COM. При этом, далеко не каждый интерфейс будет являться COM-интерфейсом.
"Но ты, по Дельфи специалист, что поведаешь нам, разница в чём или Дельфи плохо знаешь ты ?" @
Здравствуйте, hattab, Вы писали:
I>> "Но ты, по Дельфи специалист, что поведаешь нам, разница в чём или Дельфи плохо знаешь ты ?" @
H>Чтоб сильно тебя не раскармливать... В дельфях можно объявить интерфейс без GUID'а.
M>> Вопрос: можно ли в дельфях сделать интерфейс, не наследующися от IUnknown? H>Интерфейс в дельфях всегда наследуется от IInterface.
Зачем?
M>> Зачем мне обязательная зависимость/совместимость с COM'ом? H>Наличие IUnknown не делает интерфейс COM-совместимым. Сурпрайз?
Зачем тогда мне QueryInterface, AddRef и Release? Чтобы просто так были?
M>> пример:
M>>
M>> interface Bicycle {
M>> void changeCadence(int newValue); // wheel revolutions per minute
M>> void changeGear(int newValue);
M>> void speedUp(int increment);
M>> void applyBrakes(int decrement);
M>> }
M>> class ACMEBicycle implements Bicycle {
M>> // remainder of this class implemented as before
M>> }
M>>
M>> Вот нахрена мне тут IUknown? А вот он мне даром не нужен. Но нет, в Delphi я буду обязан реализовать все методы IUnknown'а или он автоматом будет реализован Delphi. Нахрена?
H>IUnknown обязателен в дельфях для гармоничного встраивания в инфраструктуру COM и вместе с тем это элегантное решение проблемы управляемого времени жизни.
Ничего нем элегантного нет. TObject не управляет временем жизни, и как-то без этого обходятся, а для интерфейсов ВНЕЗАПНО понадобилось управление?
H>Можно ли было, для поддержки интерфейсов, обойтись без IUnknown вообще? Разумеется. Но в таком случае пришлось бы разделять понятия интерфейса в рамках языка и интерфейса для COM (плюс обеспечивать механизм управления временем жизни). Какой в этом смысл? Никакого. Лишние сущности.
Лишние сущности — это насаждение QueryInterface, AddRef и Release повсюду, где они и не нужны. Нужен COM-интерфейс? Отнаследуйся себе от IInterface/IUnknown — и вперед.
H>Ситуация с интерфейсами в дельфях совершенно нормальна. Можно применять COM-совместимые интерфейсы, а можно и такие которые в рамках COM использованы быть не могут (но при этом, двух разных понятий об интерфейсах не существует). Ты не обязан самостоятельно реализовывать IUnknown, достаточно унаследоваться от класса его реализующего.
Ты не поверишь. Это возможно в любом языке с ООП. Только в нормальных языках никто не запихивает ненужные методы тебе в глотку, как это делает delphi.
В итоге что надо делать для каждого объекта? Правильно:
TMyClass = class(TInterfacedObject, IMyInterface)
потому что там, где мне даром не нужны три ненужных мне метода, я просто обязан их реализовать.
Здравствуйте, Mamut, Вы писали:
M> M>> Вопрос: можно ли в дельфях сделать интерфейс, не наследующися от IUnknown?
M> H>Интерфейс в дельфях всегда наследуется от IInterface.
M> Зачем?
Совместимость с COM + управление временем жизни. Я ведь написал уже.
M> M>> Зачем мне обязательная зависимость/совместимость с COM'ом?
M> H>Наличие IUnknown не делает интерфейс COM-совместимым. Сурпрайз?
M> Зачем тогда мне QueryInterface, AddRef и Release? Чтобы просто так были?
Управление временем жизни. Единое поведение интерфейсных типов.
M> H>IUnknown обязателен в дельфях для гармоничного встраивания в инфраструктуру COM и вместе с тем это элегантное решение проблемы управляемого времени жизни.
M> Ничего нем элегантного нет. TObject не управляет временем жизни, и как-то без этого обходятся, а для интерфейсов ВНЕЗАПНО понадобилось управление?
Было бы лучше, если бы для COM-интерфейсов время жизни было управляемым, а для остальных нет? Зачем плодить сущности без надобности?
M> H>Можно ли было, для поддержки интерфейсов, обойтись без IUnknown вообще? Разумеется. Но в таком случае пришлось бы разделять понятия интерфейса в рамках языка и интерфейса для COM (плюс обеспечивать механизм управления временем жизни). Какой в этом смысл? Никакого. Лишние сущности.
M> Лишние сущности — это насаждение QueryInterface, AddRef и Release повсюду, где они и не нужны. Нужен COM-интерфейс? Отнаследуйся себе от IInterface/IUnknown — и вперед.
Нафиг нужно это разграничение (COM/не COM), когда для поддержки обоих видов требуется идентичная функциональность?
M> H>Ситуация с интерфейсами в дельфях совершенно нормальна. Можно применять COM-совместимые интерфейсы, а можно и такие которые в рамках COM использованы быть не могут (но при этом, двух разных понятий об интерфейсах не существует). Ты не обязан самостоятельно реализовывать IUnknown, достаточно унаследоваться от класса его реализующего.
M> Ты не поверишь. Это возможно в любом языке с ООП. Только в нормальных языках никто не запихивает ненужные методы тебе в глотку, как это делает delphi.
Я не знаю, чего тебе дельфя в глотку запихивала... Назови пару языков работающих в нативе (ключевой момент), которые имеют реализацию интерфейсов отличную от реализации COM-интерфейсов. При этом обеспечивают бесшовную интероперабельность с этим самым COM. Или даже не с COM, а с интерфейсами своих же нативных модулей от другого вендора.
M> В итоге что надо делать для каждого объекта? Правильно: M>
M>> M>> Вопрос: можно ли в дельфях сделать интерфейс, не наследующися от IUnknown? M>> H>Интерфейс в дельфях всегда наследуется от IInterface. M>> Зачем?
H>Совместимость с COM + управление временем жизни. Я ведь написал уже.
Стоп. То у тебя интерфейсы совместимы с COM, то они не совместимы. Ты уже определись
M>> H>IUnknown обязателен в дельфях для гармоничного встраивания в инфраструктуру COM и вместе с тем это элегантное решение проблемы управляемого времени жизни. M>> Ничего нем элегантного нет. TObject не управляет временем жизни, и как-то без этого обходятся, а для интерфейсов ВНЕЗАПНО понадобилось управление?
H>Было бы лучше, если бы для COM-интерфейсов время жизни было управляемым, а для остальных нет? Зачем плодить сущности без надобности?
Это не плождение сущностей без надобности. Интерфейс — это вообще, по сути, абстрактный класс, контракт на исполнение. IInterface обязует всю наследующую цепочку реализовывать определенный контракт. Который даром не сдался для не-COM сущностей. Который ларом не сдался для сущностей, которые не обязаны быть COM-совместимыми.
M>> H>Можно ли было, для поддержки интерфейсов, обойтись без IUnknown вообще? Разумеется. Но в таком случае пришлось бы разделять понятия интерфейса в рамках языка и интерфейса для COM (плюс обеспечивать механизм управления временем жизни). Какой в этом смысл? Никакого. Лишние сущности.
M>> Лишние сущности — это насаждение QueryInterface, AddRef и Release повсюду, где они и не нужны. Нужен COM-интерфейс? Отнаследуйся себе от IInterface/IUnknown — и вперед.
H>Нафиг нужно это разграничение (COM/не COM), когда для поддержки обоих видов требуется идентичная функциональность?
С какоко перепугу она вдруг требуется? ТО, что так сделали в Delphi — ну так это проблемы Delphi, что они изначально все на COM завязали.
M>> H>Ситуация с интерфейсами в дельфях совершенно нормальна. Можно применять COM-совместимые интерфейсы, а можно и такие которые в рамках COM использованы быть не могут (но при этом, двух разных понятий об интерфейсах не существует). Ты не обязан самостоятельно реализовывать IUnknown, достаточно унаследоваться от класса его реализующего.
M>> Ты не поверишь. Это возможно в любом языке с ООП. Только в нормальных языках никто не запихивает ненужные методы тебе в глотку, как это делает delphi.
H>Я не знаю, чего тебе дельфя в глотку запихивала... Назови пару языков работающих в нативе (ключевой момент), которые имеют реализацию интерфейсов отличную от реализации COM-интерфейсов. При этом обеспечивают бесшовную интероперабельность с этим самым COM. Или даже не с COM, а с интерфейсами своих же нативных модулей от другого вендора.
Абстрактные классы в С++ — это и есть интерфейсы. И в С++ есть бесшовная связка с COM. Не путай мух и котлет. Мухи отдельно, котлеты отдельно.
Нативный-ненативный значения не имеет. Интерфейсы вообще к COM'у никакого отношения не имеют.
M>> В итоге что надо делать для каждого объекта? Правильно: M>>
M>> потому что там, где мне даром не нужны три ненужных мне метода, я просто обязан их реализовать.
H>А в чем принципиальный затык наследования от TInterfacedObject, вместо TObject, кроме маразматического эстетства?
В том, что никому даром не уперлись QueryInterface, AddRef и Release, кроме как в случае работы с COM'ом. И обязательная совместимость с COM'ом тоже даром не упала. Нужна совместимость с COM'ом — вперед, наследуйся от IINterface/TInterfacedObject и радуйся жизни, как это во всех нормальных языках делают.
Здравствуйте, hattab, Вы писали:
I>> Поскольку интерфейсы наследуются от ИНТЕРФЕЙСА который УЖЕ имеет ГУИД, то никаких других гуидов добавлять не нужно — интерфейс уже будет COM-интерфейсом просто потому что наследуется от IUnknown.
H> Знаток, мля. Как же ты будешь получать интерфейс без GUID'а при отсутствии compiller magic (а коль скоро мы говорим о COM, то таки там ее нет)? Вот получил ты на вход IUnknown от другого модуля. Как ты получишь IMyIntf если не знаешь его GUID?
Вопрос выдаёт дельфятника с головой
А чуть ниже был ответ на этот вопрос, то есть, ты по прежнему бежишь впереди паравоза.
I>> Гуид нужен для того, что бы запрашивать конкретный интерфейс.
H>Вот о том и речь, IMyIntf привести к IUnknown можно, а вот IUnknown к IMyIntf нельзя.
А виной всему — злоупотребление Дельфи
I>> А для самого интерфейса ГУИД не нужен, потому что он уже есть.
H>Учи мат часть, знаток. Каждый интерфейс в COM должен обладать собственным уникальным GUID. GUID не наследуется. Запросив GUID от IUnknown ты получаешь только IUnknnown.
Если не наследуется, то и IUnknown получить нельзя
Эка тебя прёт — в одном абзаце несешь ахинею и тут же себя опровергаешь.
I>> Это вовсе не мало, кстати говоря. Удивишься, но с COM можно делать много всякой всячины без назначения специального гуида на интерфейс — чисто на одном IUnknown.
H>Ну да. Без GUID'а можно счетчиком сЦылок рулить
Для COM необходимо и достаточно что бы объект реализовывал только IUnknown.
За объяснениями кури например книгу Дональда Бокса "COM Essentials"
Много чего полезного можно сделать имея только это. Кури литературу по COM.
Неудивительно, что ты опустился до гомосятины в ответ на простецкий вопрос про бровзер
Здравствуйте, Mamut, Вы писали:
M> H>Я что, непонятно написал? IUnknown нужен для совместимости с COM, но это не значит, что любой интерфейс будет совместим с COM.
M> Итак. Если они несовместимы с COM, зачем там QueryInterface, AddRef и Release? Просто так, чтобы были?
Для управления временем жизни реализующего объекта. Для унификации поведения.
M> M>> Это не плождение сущностей без надобности. Интерфейс — это вообще, по сути, абстрактный класс, контракт на исполнение. IInterface обязует всю наследующую цепочку реализовывать определенный контракт. Который даром не сдался для не-COM сущностей. Который ларом не сдался для сущностей, которые не обязаны быть COM-совместимыми.
M> H>Ты какую-то формулировку берешь за догму, и говоришь, что в дельфях оно не так, а значит все плохо? Не смеши меня больше.
M> Это не догма, это нормально определение интерфейса. И да, в дельфи интерфейсы появились только для работы с COM'ом. То, что их используют не по назначению, говоит только о недальновидности разработчиков самого Delphi.
Я использую интерфейсы безо всякого COM Я фигею с моих проблем
M> M>> H>Нафиг нужно это разграничение (COM/не COM), когда для поддержки обоих видов требуется идентичная функциональность?
M> M>> С какоко перепугу она вдруг требуется?
M> H>Для единообразия. Еще раз:
M> H>
M> H>Было бы лучше, если бы для COM-интерфейсов время жизни было управляемым, а для остальных нет?
M> Интерфейс вообще не является управляемым-неуправляемым. Интерфейс является контрактом на поведение. Он сам по себе не способен быть управляемым-неуправляемым.
M> Нужен ли QueryInterface для управляемости? Даром не нужен. M> Нужны ли AddRef и Release для управляемости? Только в рамках COM'а. В самом Delphi другой механизм управления жизнью объектами.
В рамках COM. Молодец. Теперь, если вводить в язык понятие интерфейса и при этом, в случае с интерфейсами COM, обеспечивать автоматическое управление временем жизни реализующего объекта, а в случае с не COM интерфейсами оставлять ручное, что же это получиться? Это будут проблемы на ровном месте. В дельфях сделали правильно, унифицировали поведение.
M> H>Интерфейсы там появились благодаря COM, это несомненно. И именно благодаря одному из ключевых моментов COM (QueryInterface) достигается офигительный профит при их использовании. Без аналогичного механизма поддержка интерфейсов не более чем пшик.
M> Никакого профита там нет. То, что ты имеешь реализованный в TInterfacedObject счетчик ссылок никак не влияет на миллион других объектов, наследованных от TObject. но это почему-то тебя не удивляет. А вот возможность иметь мухи и котлеты отдельно ты называешь введением доп. сущностей
Профит прямой. Получаю от сторонней dll IMethodHandler. Дергаю от него QueryInterface(IMethodSignature ...) и радуюсь жизни. Преодолены границы модулей, обеспечена интероперабельность.
M> M>> Нативный-ненативный значения не имеет. Интерфейсы вообще к COM'у никакого отношения не имеют.
M> H>Я в данном случае не о COM говорю. И нативность тут имеет самое непосредственное значение и вот почему. Если на управляемых платформах все обвешано метой и царит "полное взаимопонимание" между взаимодействующими сущностями т.к. работают они в однородной среде, то в нативе всего этого нет. Без того самого IUnknown (или его аналога) работа с интерфейсами в нативе была бы невозможна в принципе.
M> Да ты что, неужели
M> Интерфейс — это абстрактный класс. Всё. Ничем другим interface, по сути, не является. Даже в Delphi. Вон, С++ работает с COM-интерфейсами и ничего, все нормально.
С++ работает с интерфейсами извне без QueryInterface, Addref, Release? Нисмиши
M> Как и в Java, интерфейсы появились в Delphi для обхода запрета на множественное наследование.
А говорил только для COM Путаешься в показаниях... как это на тебя похоже
M> Только в Delphi интерфейсы гвоздями прибили к COM'у. Зачем? Потому что в COM'е есть множественное наследование, а разработчики Delphi не придумали ничего более умного, чем прибить к COM'у всю концепцию интерфейсов. Хотя к COM'у интерфейсы не имеют никакого отношения.
Версия интересная, но не рабочая.
M> H>Еще раз: IUnknown это не работа с COM. Это базовый элемент COM, да, но не более.
M> Который даром не нужен, если нам COM не нужен.
M> Объясняю в терминах Delphi. Предположим, в interface не заложена привязка ни к IInterface ни к IUnknown:
M>
M> IMyInterface = Interface()
M> function GetMyProperty : Boolean;
M> property myProperty : Boolean read GetMyProperty;
M> end;
M> // TMyСlass по сути является TObject'ом, мы указали ему контракт
M> // он обязан реализовать метод GetMyProperty
M> TMyClass = class(TObject, IMyInterface)
M> ...
M> // реализуем IUnknown, как в любом человеческом языке
M> IUnnknown = Interface()
M> function QueryInterface : Interface;
M> function AddRef : Ref;
M> function Release : Boolean;
M> end;
M> // TInterfacedObject обязан реализовать методы из интерфейса
M> TInterfacedObject = class(TObject, IUnknown)
M> // Пишем класс, в котором нам нужны COM-методы. У нужны они нам только тут,
M> // а не в TMyClass выше
M> TMyCOMClass = class(TInterfacedObject, IMyInterface)
M>
M> Мир внезапно перевернулся? Нет. Исчезла гвоздями прибитая привязанность к COM'у? Да, исчезла.
Узко мыслишь. Если бы работа с интерфейсами в дельфях ограничивалась только рамками одного приложения и только набором его собственных интерфейсов...
з.ы.
В общем, я вижу, прошлые споры на пользу тебе не пошли. Да и хрен с ним, проблемы твои. Это однако не отменяет факта, что твой тезис:
в Delphi не было не-COM интерфейсов.
Не соответствует действительности. За сим прощаюсь.
Здравствуйте, Ikemefula, Вы писали:
I> I>> Поскольку интерфейсы наследуются от ИНТЕРФЕЙСА который УЖЕ имеет ГУИД, то никаких других гуидов добавлять не нужно — интерфейс уже будет COM-интерфейсом просто потому что наследуется от IUnknown.
I> H> Знаток, мля. Как же ты будешь получать интерфейс без GUID'а при отсутствии compiller magic (а коль скоро мы говорим о COM, то таки там ее нет)? Вот получил ты на вход IUnknown от другого модуля. Как ты получишь IMyIntf если не знаешь его GUID?
I> Вопрос выдаёт дельфятника с головой
I> А чуть ниже был ответ на этот вопрос, то есть, ты по прежнему бежишь впереди паравоза.
I> I>> Гуид нужен для того, что бы запрашивать конкретный интерфейс.
I> H>Вот о том и речь, IMyIntf привести к IUnknown можно, а вот IUnknown к IMyIntf нельзя.
I> А виной всему — злоупотребление Дельфи
I> I>> А для самого интерфейса ГУИД не нужен, потому что он уже есть.
I> H>Учи мат часть, знаток. Каждый интерфейс в COM должен обладать собственным уникальным GUID. GUID не наследуется. Запросив GUID от IUnknown ты получаешь только IUnknnown.
I> Если не наследуется, то и IUnknown получить нельзя
I> Эка тебя прёт — в одном абзаце несешь ахинею и тут же себя опровергаешь.
I> I>> Это вовсе не мало, кстати говоря. Удивишься, но с COM можно делать много всякой всячины без назначения специального гуида на интерфейс — чисто на одном IUnknown.
I> H>Ну да. Без GUID'а можно счетчиком сЦылок рулить
I> Для COM необходимо и достаточно что бы объект реализовывал только IUnknown.
I> За объяснениями кури например книгу Дональда Бокса "COM Essentials"
I> Много чего полезного можно сделать имея только это. Кури литературу по COM.
I> Неудивительно, что ты опустился до гомосятины в ответ на простецкий вопрос про бровзер
Как ты звонко слился Удачного плаванья в родной среде
M>>Только в нормальных языках никто не запихивает ненужные методы тебе в глотку, как это делает delphi.
Т>Что, таки никто не запихивает clone, finalize, hashCode etc?
Они являются обязательными для кажого интерфейса или для наследников Object'а? Это принципиальная разница
Здравствуйте, Mamut, Вы писали:
M>Любой интерфейс в Delphi является COM-интерфейсом (так как обязывает реализовывать COM-минимум). M>Любая реализация любого интерфейса в Delphi является COM-классом/объектом (так как обязана реализовывать COM-минимум).
COM-совместимым или COM-подобным? Т.к. у меня строгая ассоциация: COM интерфейс должен иметь свой guid; иначе, это просто интерфейс реализующий IUnk., причем реализовать методы AddRef, Release — можно по своему, вопреки СОМ канону =)
Здравствуйте, Klikujiskaaan, Вы писали:
K>COM-совместимым или COM-подобным? Т.к. у меня строгая ассоциация: COM интерфейс должен иметь свой guid; иначе, это просто интерфейс реализующий IUnk.,
Господи, ну был же ответ именно там где ты скипнул:
Here is the bare minimum required for a COM interface:
class CMyClass : public IUnknown
{
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, Klikujiskaaan, Вы писали:
K>>COM-совместимым или COM-подобным? Т.к. у меня строгая ассоциация: COM интерфейс должен иметь свой guid; иначе, это просто интерфейс реализующий IUnk.,
I>Господи, ну был же ответ именно там где ты скипнул:
I>
I>Here is the bare minimum required for a COM interface:
I>class CMyClass : public IUnknown
I>{
Здравствуйте, hattab, Вы писали:
H>У дельфей все в порядке, не беспокойся.
У дельфи с интерфейсами COM все в порядке. У VB все в порядке. У С++ все в порядке. У С# (или дотнета) все в порядке. И вообще у всех, кто использует COM, должно быть все в пордяке. Потому что иначе нельзя — это двоичный стандарт.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD> H>У дельфей все в порядке, не беспокойся.
PD> У дельфи с интерфейсами COM все в порядке. У VB все в порядке. У С++ все в порядке. У С# (или дотнета) все в порядке. И вообще у всех, кто использует COM, должно быть все в пордяке. Потому что иначе нельзя — это двоичный стандарт.
Тут спор о том, что у дельфей нет не COM-интерфейсов (а они есть).
PD>> H>У дельфей все в порядке, не беспокойся.
PD>> У дельфи с интерфейсами COM все в порядке. У VB все в порядке. У С++ все в порядке. У С# (или дотнета) все в порядке. И вообще у всех, кто использует COM, должно быть все в пордяке. Потому что иначе нельзя — это двоичный стандарт.
H>Тут спор о том, что у дельфей нет не COM-интерфейсов (а они есть).
Только реализуя любой интерфейс, ты получаешь на руках COM-объект. Вот ведь парадокс-то
Здравствуйте, Mamut, Вы писали:
M> PD>> H>У дельфей все в порядке, не беспокойся.
M> PD>> У дельфи с интерфейсами COM все в порядке. У VB все в порядке. У С++ все в порядке. У С# (или дотнета) все в порядке. И вообще у всех, кто использует COM, должно быть все в пордяке. Потому что иначе нельзя — это двоичный стандарт.
M> H>Тут спор о том, что у дельфей нет не COM-интерфейсов (а они есть).
M> Только реализуя любой интерфейс, ты получаешь на руках COM-объект. Вот ведь парадокс-то
Никакого парадокса. COM-совместимость никто не отрицал Приподнимай забрало иногда
Здравствуйте, hattab, Вы писали:
H>Совместимость с COM + управление временем жизни. Я ведь написал уже.
... H>Управление временем жизни. Единое поведение интерфейсных типов.
ты мне вот что разъясни.
есть иерархия классов на основе обычного наследования.
мне потребовалось добавить интерфейс для некоторых классов. Простой такой интерфейс, без совместимости с комом(точнее мне глубоко наплевать на эту совместимость, ибо задача у меня другая). у меня 3 пути.
1. Базовый класс наследовать от TInterfacedObject, в нужных классах добавить свой интерфейс, реализовав нужные мне методы.
2. В нужных классах добавить свой интерфейс, сделав заглушки(не знаю нужно ли их реализовывать по всем правилам кома) в каждом классе для методов QueryInterface, AddRef и Release. + конечно же реализовав методы в своем интерфейсе.
3. В нужных классах добавить свой интерфейс, реализовав только свои методы.
все верно? ничего не упустил?
Вот с 3 вариантом все понятно, у меня так не получится. Получится в плюсах, и на шарпе, и на яве... Но в делфи, увы, я понуро пойду рассматривать другие варианты.
Второй вариант универсален, но мне придется делать заглушки в каждом классе. Если классов 10 будет 30 заглушек в дополнении к моим методам.
Первый вариант лучше всех остальных и в принципе с ним можно жить, если возможно изменить верхнего предка (т.е. базовый класс — мой). но если нет — то увы, единстенный вариант — второй.
Ах да забыл еще упомянуть, что все мои объекты нормально чистятся ручками на данный момент и менять это надобности нет.
Так где же это единообразие о котором ты говоришь?
H>Было бы лучше, если бы для COM-интерфейсов время жизни было управляемым, а для остальных нет? Зачем плодить сущности без надобности?
ага!
Здравствуйте, hattab, Вы писали:
H>Для единообразия. Еще раз: H>
M> H>Было бы лучше, если бы для COM-интерфейсов время жизни было управляемым, а для остальных нет?
Ну, например, в С++ интерфейс может реализовать и автоматический объект, и агрегированный и т. д.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, hattab, Вы писали:
H>Без того самого IUnknown (или его аналога) работа с интерфейсами в нативе была бы невозможна в принципе.
Странно, как-то. В С++ возможна, а в ООПнутом паскале нет?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, saturas, Вы писали:
S>Здравствуйте, hattab, Вы писали:
S>ты мне вот что разъясни. S>есть иерархия классов на основе обычного наследования. S>мне потребовалось добавить интерфейс для некоторых классов. Простой такой интерфейс, без совместимости с комом(точнее мне глубоко наплевать на эту совместимость, ибо задача у меня другая)
... S>все мои объекты нормально чистятся ручками на данный момент и менять это надобности нет.
Пишешь хелпер для своего базового класса.
type
MyHelper = class helper for TMyBaseObject
strict protected
function QueryInterface(const IID: TGUID; out Obj): HResult; virtual; stdcall;
function _AddRef: Integer; virtual; stdcall;
function _Release: Integer; virtual; stdcall;
end;
...
function MyHelper.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
if GetInterface(IID, Obj) then
Result := 0
else
Result := E_NOINTERFACE;
end;
function MyHelper._AddRef: Integer;
begin
Result := -1;
end;
function MyHelper._Release: Integer;
begin
Result := -1;
end;
1. Менять верхнего предка не надо.
2. Время жизни интерфейсов не самоуправляемо.
3. Никаких заглушек для потомков не надо.
M>> PD>> H>У дельфей все в порядке, не беспокойся.
M>> PD>> У дельфи с интерфейсами COM все в порядке. У VB все в порядке. У С++ все в порядке. У С# (или дотнета) все в порядке. И вообще у всех, кто использует COM, должно быть все в пордяке. Потому что иначе нельзя — это двоичный стандарт.
M>> H>Тут спор о том, что у дельфей нет не COM-интерфейсов (а они есть).
M>> Только реализуя любой интерфейс, ты получаешь на руках COM-объект. Вот ведь парадокс-то
H>Никакого парадокса. COM-совместимость никто не отрицал Приподнимай забрало иногда
Итак. В пятижесятый раз спрашиваю? Нахрена мне COM-совместимость там, где она мне не нужна даже даром? Так, чтобы просто была?
S>>ты мне вот что разъясни. S>>есть иерархия классов на основе обычного наследования. S>>мне потребовалось добавить интерфейс для некоторых классов. Простой такой интерфейс, без совместимости с комом(точнее мне глубоко наплевать на эту совместимость, ибо задача у меня другая) I>... S>>все мои объекты нормально чистятся ручками на данный момент и менять это надобности нет.
I>Пишешь хелпер для своего базового класса.
I>
I>type
I> MyHelper = class helper for TMyBaseObject
I> strict protected
I> function QueryInterface(const IID: TGUID; out Obj): HResult; virtual; stdcall;
I> function _AddRef: Integer; virtual; stdcall;
I> function _Release: Integer; virtual; stdcall;
I> end;
I>...
I>function MyHelper.QueryInterface(const IID: TGUID; out Obj): HResult;
I>begin
I> if GetInterface(IID, Obj) then
I> Result := 0
I> else
I> Result := E_NOINTERFACE;
I>end;
I>function MyHelper._AddRef: Integer;
I>begin
I> Result := -1;
I>end;
I>function MyHelper._Release: Integer;
I>begin
I> Result := -1;
I>end;
I>
I>1. Менять верхнего предка не надо. I>2. Время жизни интерфейсов не самоуправляемо. I>3. Никаких заглушек для потомков не надо.
Это все, практически, делает TInterfacedObject. Который реализует те самые QueryInterface и проч. Ключевой вопрос — нафига? То есть — нафига мне эти методы вообще?
Здравствуйте, Erop, Вы писали:
E> H>Для единообразия. Еще раз:
E> H>
M> H>Было бы лучше, если бы для COM-интерфейсов время жизни было управляемым, а для остальных нет?
E> Ну, например, в С++ интерфейс может реализовать и автоматический объект, и агрегированный и т. д.
В дельфях тоже и что О другом речь... Ты походу не читатель нифига Вот Мамут говорит, а что мешало сделать интерфейсы в дельфях без наследования от IUnknown? Я говорю, да ничего не мешало, но для единообразия поведения с COM интерфейсами, обычным интерфейсам тоже пришлось бы обеспечивать механизм управления жизни реализующих объектов. Итого, существовало бы два механизма делающих ровно одно и то же. Зачем? Оставить обычные интерфейсы без схожего механизма было бы еще большей ошибкой т.к. только добавило бы путаницы. В общем то сугубо прагматическое решение, отчего-то вызывающее жуткий баттхерт неосиляторов
И еще раз для всех:
Интерфейс без GUID'а не является COM интерфейсом.
PSDK:
COM interfaces are strongly typed. Every interface has its own interface identifier (a GUID), which eliminates the possibility of duplication that could occur with any other naming scheme.
IMyIntf = Interface
Procedure SayHello;
End;
IMyIntf не является COM-интерфейсом. До кого все еще не дошло, тем к доктору за целительной лоботомией
Здравствуйте, Erop, Вы писали:
E> H>Без того самого IUnknown (или его аналога) работа с интерфейсами в нативе была бы невозможна в принципе.
E> Странно, как-то. В С++ возможна, а в ООПнутом паскале нет?
Блин, а если не дергать фразы из контекста? Там же целый абзац, поясняющий смысл... Представь себе, что и в ООПнутом паскале работа с интерфейсами без IUnknown и аналогичного механизма возможна (и она, таки, прямо сейчас используется). Но я же говорю не только о конкретном, отдельно взятом, паскале или си. Я говорю о нативной среде. Там где работает compiler magic (или используется мета из управляемых сред) нафиг не нужны ни какие QueryInterface, другое дело, когда речь идет о нативной среде вообще (и как я уже сказал, принимаемые решения авторами языка не могли не учитывать сего факта). И тут без механизма аналогичного IUnknown не обойтись.
Здравствуйте, saturas, Вы писали:
s> ты мне вот что разъясни. s> есть иерархия классов на основе обычного наследования. s> мне потребовалось добавить интерфейс для некоторых классов. Простой такой интерфейс, без совместимости с комом(точнее мне глубоко наплевать на эту совместимость, ибо задача у меня другая). у меня 3 пути.
s> 1. Базовый класс наследовать от TInterfacedObject, в нужных классах добавить свой интерфейс, реализовав нужные мне методы.
Самый простой, и обычно самый правильный вариант.
s> 2. В нужных классах добавить свой интерфейс, сделав заглушки(не знаю нужно ли их реализовывать по всем правилам кома) в каждом классе для методов QueryInterface, AddRef и Release. + конечно же реализовав методы в своем интерфейсе.
Тоже можно. Реализовывать не обязательно, если не беспокоит управление временем жизни и запрос интерфейсов по GUID.
s> 3. В нужных классах добавить свой интерфейс, реализовав только свои методы. s> все верно? ничего не упустил? s> Вот с 3 вариантом все понятно, у меня так не получится.
Здравствуйте, Mamut, Вы писали:
M> M>> Только реализуя любой интерфейс, ты получаешь на руках COM-объект. Вот ведь парадокс-то
M> H>Никакого парадокса. COM-совместимость никто не отрицал Приподнимай забрало иногда
M> Итак. В пятижесятый раз спрашиваю? Нахрена мне COM-совместимость там, где она мне не нужна даже даром? Так, чтобы просто была?
M> H>Было бы лучше, если бы для COM-интерфейсов время жизни было управляемым, а для остальных нет?
E>> Ну, например, в С++ интерфейс может реализовать и автоматический объект, и агрегированный и т. д.
H>В дельфях тоже и что О другом речь... Ты походу не читатель нифига Вот Мамут говорит, а что мешало сделать интерфейсы в дельфях без наследования от IUnknown? Я говорю, да ничего не мешало, но для единообразия поведения с COM интерфейсами, обычным интерфейсам тоже пришлось бы обеспечивать механизм управления жизни реализующих объектов.
Интерфейсы ничего не реализуют. Реализуют классы. Так, TInterfacedObject реализует класс iUnknown. Этого — достаточно, чтобы не засорять интерфейсы обязательным наличием COM-методов.
H>Итого, существовало бы два механизма делающих ровно одно и то же. Зачем? Оставить обычные интерфейсы без схожего механизма было бы еще большей ошибкой т.к. только добавило бы путаницы. В общем то сугубо прагматическое решение, отчего-то вызывающее жуткий баттхерт неосиляторов
Неосилил только ты. Интерфейсы ничего не реализуют. Если тебе нужен COM, берешь интерфейс IUnknown, yаследуешься от него и реализуешь его методы. Так, как это делает TInterfacedObject. И это нужно только тогода, когда тебе нужен COM. Для всех других случаев COM не нужен даром, потому что Delphi реализует другой механизм управления жизнью объектов.
E>> H>Без того самого IUnknown (или его аналога) работа с интерфейсами в нативе была бы невозможна в принципе.
E>> Странно, как-то. В С++ возможна, а в ООПнутом паскале нет?
H>Блин, а если не дергать фразы из контекста? Там же целый абзац, поясняющий смысл... Представь себе, что и в ООПнутом паскале работа с интерфейсами без IUnknown и аналогичного механизма возможна (и она, таки, прямо сейчас используется). Но я же говорю не только о конкретном, отдельно взятом, паскале или си. Я говорю о нативной среде. Там где работает compiler magic (или используется мета из управляемых сред) нафиг не нужны ни какие QueryInterface, другое дело, когда речь идет о нативной среде вообще (и как я уже сказал, принимаемые решения авторами языка не могли не учитывать сего факта). И тут без механизма аналогичного IUnknown не обойтись.
Тебе об этом же и говорят. Вон — С++ весь из себя нативный, но никто не заставляет там в каждом абстрактном классе (аналог интерфейсов из deplhi) иметь COM-методы.
Так как интерфейс — это всего лишь контракт на поведение класса, то никто не мешает иметь интерфейсы без IUnknown'ых методов. Нужен IUnknown? Пишем интерфейс IUnknown и реализуем его в TInterfacedObject. Все. Нужен COM-интерфейс? Наследуем его от IUnknown. Не нужен COM-интерфейс? Не наследуем.
Здравствуйте, Mamut, Вы писали:
M>1. В Delphi жизнь TObject'ов управляется совсем по другому, нежели жизнь COM-объектов
В Delphi жизнь TObject'ов никак не управляется. В общем случае действует простое правило — кто создал объект должен его и уничтожить, или поручить уничтожение другому объекту. Delphi сама никогда не уничтожает объекты — в Delphi нет дефолтных деструкторов.
M>2. Почему-то тебе ничего не мешает наследоваться от TObject'ов и полагаться на чисто-дельфиские методы управления их жизнью
В Delphi жизнь TObject'ов никак не управляется.
M>3. Но при этом ты продолжаешь быть уверен, что для объектов, реализующих интерфейсы просто таки необходим подход COM для управления их жизнью,
И спорящий с тобой правильно делает — в Delphi жизнь TObject'ов никак не управляется. Единственный способ, с помощью которого в Delphi можно например реализовать RAII — это интерфейсы работающие через подсчёт ссылок.
M>несмотря на то, что: M>4. Интерфейс является всего лишь, по сути, абстрактным классом и ничто не мешает иметь интерфейсы для взаимодействия с COM-ом (как это делается в том же C++), а в тех случаях, когда COM не нужен даром, не заставлять никого реализовывать COM-методы и получать в итоге COM-объекты.
Это в С++. Интерфейсы Delphi не являются абстрактными классами. Если тебе нужен абстрактный класс — сделай абстрактный класс, никто не мешает. Безо всяких IUnknown.
M>>Вопрос: можно ли в дельфях сделать интерфейс, не наследующися от IUnknown? Зачем мне обязательная зависимость/совместимость с COM'ом?
M>Вопрос из серии: можно ли в Delphi создать объект, не наследуемый от TObject. Зачем эта обязательная совместимость? Зачем все эти методы, которые в нем имеются?
Вопрос немного совсем не из той серии.
M>На самом деле все намного проще. Это особенность реализации. Имеет смысл говорить о том, какой оверхид будет при использовании этих особенностей. Говорить о том, можно ли реализовать CORBA-интерфейс. Какой процент задач можно решить при помощи этой концепции.
Видно, как эта «особенность» реализации (а на самом деле — банальная недальновидность разработчиков) явно сказалась на пользователях дельфи, которые (если судит по хаттабу) уверены, что интерфейсы должны быть только COM-совместимыми и больше никакими
Здравствуйте, lazy_walrus, Вы писали:
M>>2. Почему-то тебе ничего не мешает наследоваться от TObject'ов и полагаться на чисто-дельфиские методы управления их жизнью _>В Delphi жизнь TObject'ов никак не управляется.
"Никак не управляется" — тоже вариант управления
M>>3. Но при этом ты продолжаешь быть уверен, что для объектов, реализующих интерфейсы просто таки необходим подход COM для управления их жизнью, _>И спорящий с тобой правильно делает — в Delphi жизнь TObject'ов никак не управляется. Единственный способ, с помощью которого в Delphi можно например реализовать RAII — это интерфейсы работающие через подсчёт ссылок.
Вот это интересно. Т.е. теперь оказывается, что интерфейсы в Delphi введены для RAII? Гм. И поэтому реализация TInterfacedObject такова, что RAII на нем не фига не работает. Оригинально
AG>>>Это не хак, это — решение. M>>Это все же хак, не позволяющий реализовать не-COM объекты с помощью интерфейсов AG>От добавления методов IInterface в каждый интерфейс больше пользы, чем вреда.
В чем там польза? В том, что каждый создаваемый в итоге объект является COM-объектом, даже тогда когда это нафиг не нужно? То, что реализующий интерфейсы объект вызывает проблемы при попытке его использровать внутри иерархии объектов Delphi?
AG>Или по-твоему, наследование любого объекта от TObject в Delphi, как и наличие подобного общего предка в других языках — тоже хак?
Наследование от TObject не является гвоздями прибитым костылем. Если в Delphi так нужна иерархия от единого предка, то можно было спокойно наследоваться от единого TInterface, а не от COM-овского IUnknown
Здравствуйте, Mamut, Вы писали:
AG>>>>Это не хак, это — решение. M>>>Это все же хак, не позволяющий реализовать не-COM объекты с помощью интерфейсов AG>>От добавления методов IInterface в каждый интерфейс больше пользы, чем вреда.
M>В чем там польза?
В возможности безопасных кастов и в управлении жизнью объектов средствами компилятора.
M>В том, что каждый создаваемый в итоге объект является COM-объектом, даже тогда когда это нафиг не нужно?
Кому это мешает?
Оверхед на объекты это добавляет, но точно также оверхед добавляет добавляет наследование от TObject и невозможность выделить память для объекта на стеке.
M>То, что реализующий интерфейсы объект вызывает проблемы при попытке его использровать внутри иерархии объектов Delphi?
И где там проблемы, вызванные наследованием от IInterface?
Там проблема в том, что полем Data нужно управлять вручную (оно ж типа простой указатель), и отустсвие\наличие наследования от IInterface не влияет.
AG>>Или по-твоему, наследование любого объекта от TObject в Delphi, как и наличие подобного общего предка в других языках — тоже хак?
M>Наследование от TObject не является гвоздями прибитым костылем.
Не вижу разницы между наследованием от TObject для объектов и наследованием от IInterface для интерфейсов
AG>>>>>Это не хак, это — решение. M>>>>Это все же хак, не позволяющий реализовать не-COM объекты с помощью интерфейсов AG>>>От добавления методов IInterface в каждый интерфейс больше пользы, чем вреда.
M>>В чем там польза? AG>В возможности безопасных кастов
При чем тут COM?
AG>и в управлении жизнью объектов средствами компилятора.
С какого перепугу компилятор вдруг начал мочь управлять жизнью этих объектов?
M>>В том, что каждый создаваемый в итоге объект является COM-объектом, даже тогда когда это нафиг не нужно? AG>Кому это мешает?
Не плоди сущностей без необходимости.
AG>Оверхед на объекты это добавляет, но точно также оверхед добавляет добавляет наследование от TObject и невозможность выделить память для объекта на стеке.
Добавляет два оверхеда — наследование от TObject (TInterfacedObject на пустом месте не появился) и реализация поддержки COM'а.
AG>>>Или по-твоему, наследование любого объекта от TObject в Delphi, как и наличие подобного общего предка в других языках — тоже хак? M>>Наследование от TObject не является гвоздями прибитым костылем. AG>Не вижу разницы между наследованием от TObject для объектов и наследованием от IInterface для интерфейсов
На вопрос это так и не отвечает — нахрена прибивать интерфейсы гвоздями к COM'у?
Здравствуйте, Mamut, Вы писали:
M>При чем тут COM?
В Delphi могли сделать то же самое несовместимым с COM образом, но зачем полдить лишние сущности, если можно взять готовый COM ?
AG>>и в управлении жизнью объектов средствами компилятора.
M>С какого перепугу компилятор вдруг начал мочь управлять жизнью этих объектов?
var I: IMyInterface;
begin
I := TMyObject.Create();
// Destroy вызовется сам.end;
M>>>В том, что каждый создаваемый в итоге объект является COM-объектом, даже тогда когда это нафиг не нужно? AG>>Кому это мешает?
M>Не плоди сущностей без необходимости.
То же самое можно сказать про все методы TObject.
M>На вопрос это так и не отвечает — нахрена прибивать интерфейсы гвоздями к COM'у?
См. выше — надо ли было делать свой IInterface, если уже есть такой в COM ?
Здравствуйте, MxMsk, Вы писали:
MM>Есть нюанс. Наследование от TObject не обязывает меня реализовывать методы, которые мне не нужны, чего не скажешь в случае наследования от IInterface.
Есть. Но реализовать их не сложно, часто достаточно наследоваться от TInterfacedObject.
Здравствуйте, Mamut, Вы писали:
M>>>Вопрос: можно ли в дельфях сделать интерфейс, не наследующися от IUnknown? Зачем мне обязательная зависимость/совместимость с COM'ом?
M>>Вопрос из серии: можно ли в Delphi создать объект, не наследуемый от TObject. Зачем эта обязательная совместимость? Зачем все эти методы, которые в нем имеются? M>Вопрос немного совсем не из той серии.
Как раз из той. Потому что интерфейсы берут свое начало из TObject:
TObject = class// .........function GetInterface(const IID: TGUID; out Obj): Boolean;
class function GetInterfaceEntry(const IID: TGUID): PInterfaceEntry;
class function GetInterfaceTable: PInterfaceTable;
// .........procedure Dispatch(var Message); virtual;
procedure DefaultHandler(var Message); virtual;
// .........end;
M>Видно, как эта «особенность» реализации (а на самом деле — банальная недальновидность разработчиков) явно сказалась на пользователях дельфи, которые (если судит по хаттабу) уверены, что интерфейсы должны быть только COM-совместимыми и больше никакими
А мне, наоборот, удобно Можно сказать и немного по-другому: при реализации интерфейсов в Delphi были заимствованы некоторые идеи из COM.
M>>При чем тут COM? AG>В Delphi могли сделать то же самое несовместимым с COM образом, но зачем полдить лишние сущности, если можно взять готовый COM ?
Угу. К.О. сообщает, что они могли это реализовать совместимым с COM'ом образом, не прибивая COM гвоздями.
AG>>>и в управлении жизнью объектов средствами компилятора.
M>>С какого перепугу компилятор вдруг начал мочь управлять жизнью этих объектов?
AG>
И при чем тут COM?
M>>>>В том, что каждый создаваемый в итоге объект является COM-объектом, даже тогда когда это нафиг не нужно? AG>>>Кому это мешает?
M>>Не плоди сущностей без необходимости.
AG>То же самое можно сказать про все методы TObject.
Которые никто не обязывает насильно реализовывать. В отличие от.
M>>На вопрос это так и не отвечает — нахрена прибивать интерфейсы гвоздями к COM'у?
AG>См. выше — надо ли было делать свой IInterface, если уже есть такой в COM ?
Потому что интерфейсы != COM. Ликбез: http://ru.wikipedia.org/wiki/Интерфейс_(объектно-ориентированное_программирование)
M>>>>Вопрос: можно ли в дельфях сделать интерфейс, не наследующися от IUnknown? Зачем мне обязательная зависимость/совместимость с COM'ом?
M>>>Вопрос из серии: можно ли в Delphi создать объект, не наследуемый от TObject. Зачем эта обязательная совместимость? Зачем все эти методы, которые в нем имеются? M>>Вопрос немного совсем не из той серии.
M>Как раз из той. Потому что интерфейсы берут свое начало из TObject:
M>
M> TObject = class
M> // .........
M> function GetInterface(const IID: TGUID; out Obj): Boolean;
M> class function GetInterfaceEntry(const IID: TGUID): PInterfaceEntry;
M> class function GetInterfaceTable: PInterfaceTable;
M> // .........
M> procedure Dispatch(var Message); virtual;
M> procedure DefaultHandler(var Message); virtual;
M> // .........
M> end;
M>
ууууу. все, оказывается, еще хуже, чем я думал.
M>>Видно, как эта «особенность» реализации (а на самом деле — банальная недальновидность разработчиков) явно сказалась на пользователях дельфи, которые (если судит по хаттабу) уверены, что интерфейсы должны быть только COM-совместимыми и больше никакими
M>А мне, наоборот, удобно Можно сказать и немного по-другому: при реализации интерфейсов в Delphi были заимствованы некоторые идеи из COM.
Угу, скорее при реализации интерфейсов, они COM не просто гвоздями прибили, но еще и привинтили болтами М9.
В этом разрезе все интереснее, как они будут реализовывать кроссплатформенный Дельфи. Забъют все заглушками, наверняка.
Здравствуйте, Mamut, Вы писали:
M>Угу, скорее при реализации интерфейсов, они COM не просто гвоздями прибили, но еще и привинтили болтами М9. M>В этом разрезе все интереснее, как они будут реализовывать кроссплатформенный Дельфи. Забъют все заглушками, наверняка.
А в чем проблема? Чем может это все помешать? Те же интерфейсы можно было юзать в Kylix. В Delphi можно создавать/юзать CORBA-интерфейсы.
M>>Угу, скорее при реализации интерфейсов, они COM не просто гвоздями прибили, но еще и привинтили болтами М9. M>>В этом разрезе все интереснее, как они будут реализовывать кроссплатформенный Дельфи. Забъют все заглушками, наверняка.
M>А в чем проблема? Чем может это все помешать? Те же интерфейсы можно было юзать в Kylix.
Ага. То есть все же заглушки, я так понимаю, были
M>В Delphi можно создавать/юзать CORBA-интерфейсы.
Опять двадцать пять. К.О. сообщает, что http://ru.wikipedia.org/wiki/Интерфейс_(объектно-ориентированное_программирование)
M>> Угу, скорее при реализации интерфейсов, они COM не просто гвоздями прибили, но еще и привинтили болтами М9.
M>> В этом разрезе все интереснее, как они будут реализовывать кроссплатформенный Дельфи. Забъют все заглушками, наверняка.
H>Какие еще заглушки, клоВун Мамут, спасибо тебе, я давно так не ржал Хоть и грешно над убогими...
Здравствуйте, Mamut, Вы писали:
M> M>> Угу, скорее при реализации интерфейсов, они COM не просто гвоздями прибили, но еще и привинтили болтами М9.
M> M>> В этом разрезе все интереснее, как они будут реализовывать кроссплатформенный Дельфи. Забъют все заглушками, наверняка.
M> H>Какие еще заглушки, клоВун Мамут, спасибо тебе, я давно так не ржал Хоть и грешно над убогими...
M> За неимением в Линуксах COM-а, убогенький ты мой
Ой, Мамут... ты такой Мамут Снова COM вспомнил Пацталом
Здравствуйте, MxMsk, Вы писали:
MM> H>Какие еще заглушки, клоВун Мамут, спасибо тебе, я давно так не ржал Хоть и грешно над убогими...
MM> Вместо того, чтобы ржать попусту да переходить на личности, ответь лучше на это
M>> M>> Угу, скорее при реализации интерфейсов, они COM не просто гвоздями прибили, но еще и привинтили болтами М9.
M>> M>> В этом разрезе все интереснее, как они будут реализовывать кроссплатформенный Дельфи. Забъют все заглушками, наверняка.
M>> H>Какие еще заглушки, клоВун Мамут, спасибо тебе, я давно так не ржал Хоть и грешно над убогими...
M>> За неимением в Линуксах COM-а, убогенький ты мой
H> Ой, Мамут... ты такой Мамут Снова COM вспомнил Пацталом
Твои слова:
IUnknown нужен для совместимости с COM
COM-совместимость никто не отрицал
в дельфях все интерфейсы наследуются от IUnknown (если быть точным — от IInterface, что суть тоже самое). Это нужно для совместимости с COM.
IUnknown обязателен в дельфях для гармоничного встраивания в инфраструктуру COM
Более того:
Без того самого IUnknown (или его аналога) работа с интерфейсами в нативе была бы невозможна в принципе
На что тебе уже не раз было замечено, что это — ложь.
MM>> H>Какие еще заглушки, клоВун Мамут, спасибо тебе, я давно так не ржал Хоть и грешно над убогими...
MM>> Вместо того, чтобы ржать попусту да переходить на личности, ответь лучше на это
Здравствуйте, Mamut, Вы писали:
M> MM>> H>Какие еще заглушки, клоВун Мамут, спасибо тебе, я давно так не ржал Хоть и грешно над убогими...
M> MM>> Вместо того, чтобы ржать попусту да переходить на личности, ответь лучше на это
.
M> H>Я уже сказал, что эту темя для себя закрыл. Ты можешь найти ответ если перечитаешь написанное ранее.
M> Конкретно на этот вопрос ты не ответил ни разу, не сливай.
Я уже понял, что у тебя терминальная стадия флудорастии и читать ты не умеешь. Успокойся.
Здравствуйте, hattab, Вы писали:
H>Я уже сказал, что эту темя для себя закрыл. Ты можешь найти ответ если перечитаешь написанное ранее.
Ты написал, что речь идет о какой-то там "нативности". Так вот я и не пойму: что ты вкладываешь в это понятие? Также был вопрос: что мешает компилятору самому генерить эти три метода?
M>> Без того самого IUnknown (или его аналога) работа с интерфейсами в нативе была бы невозможна в принципе
M>> На что тебе уже не раз было замечено, что это — ложь.
M>> Дальше — ликбез: http://ru.wikipedia.org/wiki/Интерфейс_(объектно-ориентированное_программирование)
H>Ну что я могу сказать... Мамут ты идиот Вот об этом
было сказано сильно раньше, но ты же не читаешь нихрена, или до тебя просто не доходит...
Идиотом являешься тут только ты, так как ты уверен, что для интерфейсов обязательно нужны QueryInterface и т.п. Хотя тебе не раз было сказано, что это не так.
Повторю для тебя еще раз. Есть такой язык, как С++, абстрактные классы которого являются прямыми аналогами интерфейсов из Delphi. ВНЕЗАПНО в С++ не надо никакой магии для работы этих абстрактных классов.
Для работы с COM'ом прекрасно описывается и реализуется IUnknown и иже с ним.
И только ты уверен, что для работы интерфейсов/работы с интерфейсами нужна какая-то магия или QueryInterface проч.
Специально для тебя процитирую:
интерфейс, с точки зрения реализации — это просто чистый абстрактный класс, то есть класс, в котором не определено ничего, кроме абстрактных методов.
При чем тут COM, совместимость с ним, comiler magic и обязательная реализация COM-овcких методов неизвестно никому. Тебе, в том числе (иначе ты бы про не нес весь этот бред про натив и проч.)
M>> MM>> H>Какие еще заглушки, клоВун Мамут, спасибо тебе, я давно так не ржал Хоть и грешно над убогими...
M>> MM>> Вместо того, чтобы ржать попусту да переходить на личности, ответь лучше на это
.
M>> H>Я уже сказал, что эту темя для себя закрыл. Ты можешь найти ответ если перечитаешь написанное ранее.
M>> Конкретно на этот вопрос ты не ответил ни разу, не сливай.
H>Я уже понял, что у тебя терминальная стадия флудорастии и читать ты не умеешь. Успокойся.
Если ты называешь свои ответом свой бред про то, что для поддержки интерфейсов в нативе ОБЯЗАТЕЛЬНО нужны COM-методы, то тебе пора на полочку к Шеридану. Вы прекрасно друг друга дополняете.
Здравствуйте, MxMsk, Вы писали:
MM> H>Я уже сказал, что эту темя для себя закрыл. Ты можешь найти ответ если перечитаешь написанное ранее.
MM> Ты написал, что речь идет о какой-то там "нативности". Так вот я и не пойму: что ты вкладываешь в это понятие?
Менеджед и натив различаешь? Это оно.
MM> Также был вопрос: что мешает компилятору самому генерить эти три метода?
Вопрос зачем? Иногда бывает выгодно самому релизить некоторые из этих методов, преинтересные вещи делать удается, доложу я вам (см. RIO.TRIO.QueryInterface и как там формируются интерфейсные таблицы для поддержки SOAP).
Здравствуйте, MxMsk, Вы писали:
M>>>3. Но при этом ты продолжаешь быть уверен, что для объектов, реализующих интерфейсы просто таки необходим подход COM для управления их жизнью, _>>И спорящий с тобой правильно делает — в Delphi жизнь TObject'ов никак не управляется. Единственный способ, с помощью которого в Delphi можно например реализовать RAII — это интерфейсы работающие через подсчёт ссылок.
MM>Вот это интересно. Т.е. теперь оказывается, что интерфейсы в Delphi введены для RAII?
Здравствуйте, Mamut, Вы писали:
M> Идиотом являешься тут только ты, так как ты уверен, что для интерфейсов обязательно нужны QueryInterface и т.п. Хотя тебе не раз было сказано, что это не так.
Ты мне свои бредовые идеи не приписывай. Я сказал, что в нативной среде работа с интерфейсами без аналога IUnknown является не более чем пшиком (но это, внезапно, не означает, что для интерфейсов вообще, всегда требуется IUnknown или аналоги). Вот мои слова
Интерфейсы там появились благодаря COM, это несомненно. И именно благодаря одному из ключевых моментов COM (QueryInterface) достигается офигительный профит при их использовании. Без аналогичного механизма поддержка интерфейсов не более чем пшик.
А ты свой бред можешь засунуть себе туда где зудит.
Здравствуйте, Mamut, Вы писали:
M> Если ты называешь свои ответом свой бред про то, что для поддержки интерфейсов в нативе ОБЯЗАТЕЛЬНО нужны COM-методы, то тебе пора на полочку к Шеридану. Вы прекрасно друг друга дополняете.
Я уже понял, что ты нифига не понял. Не напрягайся.
M>> Идиотом являешься тут только ты, так как ты уверен, что для интерфейсов обязательно нужны QueryInterface и т.п. Хотя тебе не раз было сказано, что это не так.
H>Ты мне свои бредовые идеи не приписывай. Я сказал, что в нативной среде работа с интерфейсами без аналога IUnknown является не более чем пшиком (но это, внезапно, не означает, что для интерфейсов вообще, всегда требуется IUnknown или аналоги). Вот мои слова
H>Интерфейсы там появились благодаря COM, это несомненно. И именно благодаря одному из ключевых моментов COM (QueryInterface) достигается офигительный профит при их использовании. Без аналогичного механизма поддержка интерфейсов не более чем пшик.
H>А ты свой бред можешь засунуть себе туда где зудит.
С чего это вдруг они будут являться пшиком? Интерфейсы — не более, чем реализация множественного наследования в языках, где множественного наследования нет (например, в Delphi). При чем тут COM'овские методы?
Здравствуйте, Mamut, Вы писали:
M>Потому что интерфейсы != COM. Ликбез: http://ru.wikipedia.org/wiki/Интерфейс_(объектно-ориентированное_программирование)
Интерфейс это семантическая и синтаксическая конструкция в коде программы, используемая для специфицирования услуг, предоставляемых классом или компонентом.
В каком месте интерфейсы Delphi не удовлетворяют этому определению?
Здравствуйте, Mamut, Вы писали:
M> С чего это вдруг они будут являться пшиком? Интерфейсы — не более, чем реализация множественного наследования в языках, где множественного наследования нет (например, в Delphi). При чем тут COM'овские методы?
Вот-вот, я и говорю, нифига ты не понимаешь... QueryInterface страшная сила, если начать думать, а не повторять зазубренные формулировки.
Здравствуйте, Mamut, Вы писали:
_>>Это в С++. Интерфейсы Delphi не являются абстрактными классами. Если тебе нужен абстрактный класс — сделай абстрактный класс, никто не мешает. Безо всяких IUnknown.
M>Дело в том, что в Delphi нет множественного наследования, и интерфейсы — это единственный способ задать разное поведение обхекту. Тольков от облом — это поведение будет гвоздями прибито к DOM'у.
Компилятор Delphi неявно вызывает AddRef и Release при работе с интерфейсами. Без QueryInterface для простых внутренних интерфейсов можно обойтись, а AddRef и Release должны быть обязательно как-то реализованы. Собственно и всё.
Здравствуйте, hattab, Вы писали:
MM>> H>Я уже сказал, что эту темя для себя закрыл. Ты можешь найти ответ если перечитаешь написанное ранее. MM>> Ты написал, что речь идет о какой-то там "нативности". Так вот я и не пойму: что ты вкладываешь в это понятие? H>Менеджед и натив различаешь? Это оно.
Вроде приводили в пример С++. Вроде нативный язык. Не?
MM>> Также был вопрос: что мешает компилятору самому генерить эти три метода? H>Вопрос зачем? Иногда бывает выгодно самому релизить некоторые из этих методов, преинтересные вещи делать удается, доложу я вам (см. RIO.TRIO.QueryInterface и как там формируются интерфейсные таблицы для поддержки SOAP).
Еще раз повторю. Затем, что мне эти методы не нужны. Их нет в моем контракте. Пофиг мне, что с ними кто-то может делать интересные вещи. Мне они зачем, м?
Здравствуйте, lazy_walrus, Вы писали:
_>>>И спорящий с тобой правильно делает — в Delphi жизнь TObject'ов никак не управляется. Единственный способ, с помощью которого в Delphi можно например реализовать RAII — это интерфейсы работающие через подсчёт ссылок. MM>>Вот это интересно. Т.е. теперь оказывается, что интерфейсы в Delphi введены для RAII? _>С какого перепоя такое умозаключение?
Выделил. Но скажу сразу, что я почему-то пропустил слово "например". Если RAII был просто примером, то ладно.
Здравствуйте, hattab, Вы писали:
M>> С чего это вдруг они будут являться пшиком? Интерфейсы — не более, чем реализация множественного наследования в языках, где множественного наследования нет (например, в Delphi). При чем тут COM'овские методы?
H>Вот-вот, я и говорю, нифига ты не понимаешь... QueryInterface страшная сила, если начать думать, а не повторять зазубренные формулировки.
Нет там ничего страшного. Упрощенный до предела бинарный стандарт.
Здравствуйте, MxMsk, Вы писали:
MM> Слушай, у тебя, что не ответ Мамуту, то попытка оскорбить. Может сбавишь обороты, а?
А тебя коим боком задевает? Это мое личное дело, тем более, что есть за что Что-то ты к Мамуту не лезешь, когда он Шеридана поливает. Искатель справедливости, мля
Здравствуйте, Ikemefula, Вы писали:
I> M>> С чего это вдруг они будут являться пшиком? Интерфейсы — не более, чем реализация множественного наследования в языках, где множественного наследования нет (например, в Delphi). При чем тут COM'овские методы?
I> H>Вот-вот, я и говорю, нифига ты не понимаешь... QueryInterface страшная сила, если начать думать, а не повторять зазубренные формулировки.
I> Нет там ничего страшного. Упрощенный до предела бинарный стандарт.
Здравствуйте, MxMsk, Вы писали:
MM> H>Менеджед и натив различаешь? Это оно.
MM> Вроде приводили в пример С++. Вроде нативный язык. Не?
Ты в курсе, что C++ это еще не вся нативная среда? О взаимодействии подумай. Ну я же об этом писал уже, ну?
MM> MM>> Также был вопрос: что мешает компилятору самому генерить эти три метода?
MM> H>Вопрос зачем? Иногда бывает выгодно самому релизить некоторые из этих методов, преинтересные вещи делать удается, доложу я вам (см. RIO.TRIO.QueryInterface и как там формируются интерфейсные таблицы для поддержки SOAP).
MM> Еще раз повторю. Затем, что мне эти методы не нужны. Их нет в моем контракте. Пофиг мне, что с ними кто-то может делать интересные вещи. Мне они зачем, м?
Не нужны — не реализуй Выбери предка с реализацией или делегируй. Тоже мне проблема
Здравствуйте, Antikrot, Вы писали:
MM>>> Слушай, у тебя, что не ответ Мамуту, то попытка оскорбить. Может сбавишь обороты, а? H>>Что-то ты к Мамуту не лезешь, когда он Шеридана поливает. A>им можно. я так вообще серьёзно думаю, что они в жаббере договариваются кто кого где и как ссаными тряпками гонять будет.
Ты святой
_>>>Это в С++. Интерфейсы Delphi не являются абстрактными классами. Если тебе нужен абстрактный класс — сделай абстрактный класс, никто не мешает. Безо всяких IUnknown.
M>>Дело в том, что в Delphi нет множественного наследования, и интерфейсы — это единственный способ задать разное поведение обхекту. Тольков от облом — это поведение будет гвоздями прибито к DOM'у.
_>Компилятор Delphi неявно вызывает AddRef и Release при работе с интерфейсами.
Зачем?
_>Без QueryInterface для простых внутренних интерфейсов можно обойтись, а AddRef и Release должны быть обязательно как-то реализованы.
Здравствуйте, Sinclair, Вы писали:
S>Какие у него были варианты? S>1. Сделать два типа интерфейсов: унаследованные от IUnknown и все остальные. Компилятор отслеживает поведение IUnknown-based, автоматически подсчитывая ссылки и преобразуя приведение типов к QueryInterface. Для "обычных" интерфейсов он этого не делает. S>Такая политика может приводить к трудноуловимым глюкам в тех случаях, когда класс реализует сразу несколько интерфейсов. Получается, разные ссылки на этот объект будут вести себя по-разному. Вот мы сохраняем ссылку на "обычный" интерфейс. Как знать, вдруг за ней скрывается объект с поддержкой IUnknown? Проверять ли это и подсчитывать ли ссылки? S>Как делать приведения к интерфейсу? Вот мы приводим "обычный" интерфейс к IUnknown-based. Возможно, он реализован через агрегацию, которая встроена в язык. Стало быть, обычный каст даст неверный результат — нужно лезть в QueryInterface.
S>В общем, что-то не клеится такая автоматика. Получаем переусложнение на ровном месте, и паранойю компилятора во всех местах использования интерфейсов типа "а вдруг там сзади COM?"
S>2. Сделать ровно один тип интерфейсов. IUnknown — такой же, как и все; никакой магии нет. Получается, для банальной работы с ком-объектами нужно везде руками писать AddRef/Release/QueryInterface. Постоянно помнить о том, что приведение типов через каст может работать-работать, а потом вдруг перестать — если реализация данного конкретного интерфейса изменилась на агрегацию. S>Работать — работает, но как-то грубо по отношению к девелоперам. Это примерно то же, что и поддержка COM в чистом C: реализовать можно, но помощи от компилятора нет.
S>3. Принудительно сделать все интерфейсы ком-совместимыми. В итоге за счёт весьма небольшой цены (фактически, припиливания 4х байт к каждому объекту, реализующему хоть какой-то интерфейс) имеем очень хорошую поддержку как разработки COM-классов, так и использования; при этом компилятор достаточно прямолинеен и предсказуем.
4. Сделать все интерфейсы простыми, без магии, а для магии добавить отдельную фичу языка, позволяющую делать автодеструкцию, причем не только для интерфейсов, а универсально.
И Хейлсберг сотоварищи, кстати, знаменит еще и тем, что вместо прибивания гвоздями к основному языку SQL, как это делали многие до него, он придумал куда как более генерализованный LINQ. Который сейчас используется вообще без БД в огромном количестве мест. И интерфейсы в Дельфи так и остались в основном средством СОМ интеропа.
Здравствуйте, hattab, Вы писали:
H>Несмотря на то, что IMyIntf наследуется от IInterface (IUnknown), сам он не является COM-интерфейсом т.к. не имеет собственного GUID'а.
GUID нужен для регистрации интерфейса и работы через QueryInterface. Однако QI не единственный способ получения ссылки на стаб интерфейса. Вполне работает в СОМ куда более банальный вариант:
interface IGuidIface
{
INoGuidIface Get();
// Или даже так
IUnknown MyQueryInterface(string ifaceName);
}
Здравствуйте, Ночной Смотрящий, Вы писали:
НС> GUID нужен для регистрации интерфейса и работы через QueryInterface. Однако QI не единственный способ получения ссылки на стаб интерфейса. Вполне работает в СОМ куда более банальный вариант: НС>
НС> interface IGuidIface
НС> {
НС> INoGuidIface Get();
НС> // Или даже так
НС> IUnknown MyQueryInterface(string ifaceName);
НС> }
НС>
Только это будет уже не COM-интерфейс. Я ведь уже приводил цитату из PSDK:
COM interfaces are strongly typed. Every interface has its own interface identifier (a GUID), which eliminates the possibility of duplication that could occur with any other naming scheme.
Здравствуйте, Ночной Смотрящий, Вы писали:
НС> Интерфейс, который прекрасно работает в чистом СОМ API, может не являтся при этом СОМ интерфейсом?
Конечно может. К COM-интерфейсу вообще предъявляется немало требований, в части реализации IUnknown, и без выполнения этих требований интерфейс не может считаться таковым.
НС> P.S. По ссылке просто упрощение, чтобы не забивать на первом этапе голову ненужными подробностями.
Да ладно, об этом в каждой книге по COM говорится. Вот еще из PSDK:
All predefined interfaces (and any custom interfaces you define) inherit their definitions from the important interface IUnknown, which contains three vital methods: QueryInterface, AddRef, and Release.
Здравствуйте, Ночной Смотрящий, Вы писали:
НС> H>С чего это вдруг? В VCL полно мест где используются интерфейсы, и интеропом с COM там даже не пахнет.
НС> На тот момент, когда я последний раз всерьез что то писал на Дельфи (лет 8 назад) таких мест практически не было. Сами интерфейсы там присутствовали уже лет 5 на тот момент.
Это в семерке то небыло? А WebSnap, IntraWeb, SOAP, MIDAS? В реализации каждой их этих немалых частей VCL используются интерфейсы (и в немалом количестве). Сейчас их используют еще шире.
Здравствуйте, hattab, Вы писали:
H>Конечно может. К COM-интерфейсу вообще предъявляется немало требований, в части реализации IUnknown, и без выполнения этих требований интерфейс не может считаться таковым.
НС>> P.S. По ссылке просто упрощение, чтобы не забивать на первом этапе голову ненужными подробностями.
H>Да ладно, об этом в каждой книге по COM говорится. Вот еще из PSDK: H>
All predefined interfaces (and any custom interfaces you define) inherit their definitions from the important interface IUnknown, which contains three vital methods: QueryInterface, AddRef, and Release.
Здравствуйте, Ночной Смотрящий, Вы писали:
НС> H>Да ладно, об этом в каждой книге по COM говорится. Вот еще из PSDK: НС> H>
All predefined interfaces (and any custom interfaces you define) inherit their definitions from the important interface IUnknown, which contains three vital methods: QueryInterface, AddRef, and Release.
НС> Круто конечно, но при чем тут GUID?
QueryInterface без GUID'а, как ты понимаешь, работать не может, а одно из правил реализации QI выглядит так:
It Must Be Possible to Query Successfully for Any Interface on an Object from Any Other Interface