Интерфейсы и указатели

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Ответить
Odyssey
энтузиаст
Сообщения: 580
Зарегистрирован: 29.11.2007 16:32:24

Интерфейсы и указатели

Сообщение Odyssey »

Есть задача -- хранить в TTreeNode.Data (тип Pointer) вместо указателей на объекты указатели на интерфейсы, что-то типа:

Код: Выделить всё

var
  mi: TMyInterface;
  TreeNode: TTreeNode;
...
mi := GetMyInterface();
TreeNode.Data := Pointer(mi);
...
TMyInterface(TreeNode.Data).MyMethod();

По поводу этого кода меня терзают смутные сомнения..
1) Если я правильно понимаю, жесткое приведение типа не должно повлиять на подсчет ссылок -- в смысле счетчик ссылок не изменится, так? И я должен поддерживать другие ссылки на тот же экземпляр интерфейса (например, mi), чтобы он не освободился сам?
2) Поскольку Data -- это уже Pointer, то любые манипуляции с его значением (присваивание его чему-то, присваивание ему чего-то) никак не отразятся на подсчете ссылок?
3) Может быть тут есть какие-нибудь грабли, про которые я забыл?
4) Можно ли всё вышесказанное отнести к такому же хранению интерфейсов в простом TList, без использования TInterfaceList?
5) Может у кого-нибудь в закладках есть хорошая статья по внутреннему устройству интерфейсов? А то слово Interface -- не очень google-friendly..
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
Сообщения: 1409
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Sergei I. Gorelkin »

Вроде бы все вроде правильно в рассуждениях.
Найдешь грабли - сообщай.
И еще, если не затачиваться под Дельфи, можно объявить {$interfaces corba} в начале модуля - и никаких проблем со счетчиками ссылок не будет вообще, равно как и самих счетчиков.
Odyssey
энтузиаст
Сообщения: 580
Зарегистрирован: 29.11.2007 16:32:24

Сообщение Odyssey »

Ок, спасибо.
Аватара пользователя
Alexx2000
постоялец
Сообщения: 491
Зарегистрирован: 25.10.2006 00:22:07
Откуда: Мытищи
Контактная информация:

Сообщение Alexx2000 »

Odyssey писал(а):5) Может у кого-нибудь в закладках есть хорошая статья по внутреннему устройству интерфейсов? А то слово Interface -- не очень google-friendly..

Вот у меня завалялась ссылка, правда не знаю насколько она будет полезна...
alexrayne
постоялец
Сообщения: 125
Зарегистрирован: 03.12.2008 15:56:26

Сообщение alexrayne »

кажись с CORBA интерфейсами у фрюхи было невсе впорядке.конкретно с интерфейсами без гуида - нельзя было в версии 2.2.2 получить интерфейс от объекта оператором as.
как нынче невкурсе.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
Сообщения: 1409
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Sergei I. Gorelkin »

Нынче это пофиксили. 'as' работает с corba-интерфейсами, но идентификатор интерфейса таки должен присутствовать (это может быть любая строка, в том числе и в формате GUID).
alexrayne
постоялец
Сообщения: 125
Зарегистрирован: 03.12.2008 15:56:26

Сообщение alexrayne »

вот етого я непонимаю. накой болт он нужен етот гуид. насколько я понимаю это используется при поиске интерфейса в винде. и вообще гуид изобретение микрософта. идею интерфейсов я впервые посмотрел в Ада2006. мне понравилось что они сделали. потом увидел что в дельфе похоже. и вот во фрюхе облом.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
Сообщения: 1409
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Sergei I. Gorelkin »

Ну а что еще можно использовать в виде идентификатора? Аналог TClass у интерфейсов отсутствует, да он, как и любой другой указатель, не будет работать через границу модулей. Оставили строку (строчный литерал).
alexrayne
постоялец
Сообщения: 125
Зарегистрирован: 03.12.2008 15:56:26

Сообщение alexrayne »

если вы работаете в винде пытаясь получить интерфейс от стороннейц программы, которая написана другим разработчиком и наверно на другом языке, то вам ессно необходимо какоето имя етому интерфейсу по которому вы его сможете запросить, просто чтобы 2 программы договорились друг с другом.

а если я использую локальные интерфейсы, для того чтобы както сэмулировать множественное наследие, то раз уж программа целиком компилируется компилятором то ему и флаг в руки каким способом он получит и найдет интерфейсы.

насколько я понял интерфейс ето чтото вроде указателя на VMT. VMT класса содержит специальную таблицу с перечнем интерфейсов. как далее происходит доступ интерфейсу для меня загадка. Но сильно подозреваю что оно происходит через жопу.
я невижу никаких проблем найти VMT нитерфейса, ведь VMT класса любого предка компилятор легко может найти, даже если они вообще неиспользуются в программе.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
Сообщения: 1409
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Sergei I. Gorelkin »

VMT класса найти легко, потому что они есть. "VMT интерфейса" как самостоятельная сущность в программе отсутствует. Есть VMT пар "интерфейс+реализация", т.е. у каждого класса, реализующего интерфейс, будет своя VMT для этого интерфейса. И то, только в том случае, если класс реализует интерфейс непосредственно. В случае делегирования вместо VMT будет информация о том, где ее искать дальше.

Поэтому компилятор "знает" об интерфейсах не настолько много, как может показаться. При приведении типа класса к интерфейсу
intf := ISomeInterface(myobject), если myobject реализует ISomeInterface непосредственно, можно обойтись без идентификатора интерфейса. Во всех остальных случаях он нужен.
alexrayne
постоялец
Сообщения: 125
Зарегистрирован: 03.12.2008 15:56:26

Сообщение alexrayne »

VMT класса найти легко, потому что они есть. "VMT интерфейса" как самостоятельная сущность в программе отсутствует. Есть VMT пар "интерфейс+реализация", т.е. у каждого класса, реализующего интерфейс, будет своя VMT для этого интерфейса. И то, только в том случае, если класс реализует интерфейс непосредственно. В случае делегирования вместо VMT будет информация о том, где ее искать дальше.

ето конешно понятно, но ведь вопрос не в том что ему надо какаято информация об интерфейсе. ето и ежу ясно. вопрос в том накой ему гуид чтобы идентефицировать нтерфейс? ведь мало того что гуид огромен (128бит вроде), так он еще сам и непридумается, похорошему его у мелкософта надо выпрашивать.

Аде для идентификации как класса так и интерфейса нужен был лиш тег (ада вообще постаралась уйти от указателей), если разновидностей классов в программе мало, то наверное тег может занимать и один байт всего.

указателя полюбому должно хватить для идентификации любого объекта, ведь больше объектов чем ячеек в памяти вы ненаплодите. файловая система для поиска файла использует строку, но если уж он найден и открыт, достаточно Handle.

Поэтому компилятор "знает" об интерфейсах не настолько много, как может показаться. При приведении типа класса к интерфейсу
intf := ISomeInterface(myobject), если myobject реализует ISomeInterface непосредственно, можно обойтись без идентификатора интерфейса. Во всех остальных случаях он нужен.


ну так что же мешает компилятору создать етот идетнификатор, почему задача его создания взваливается на програмиста? ето тоже самое как эмулировать объекты вручную - создавать самому таблицы VMT, связывать их, и т.п.....
Павел Ишенин
постоялец
Сообщения: 475
Зарегистрирован: 24.03.2007 09:16:52

Сообщение Павел Ишенин »

alexrayne писал(а):ведь мало того что гуид огромен (128бит вроде), так он еще сам и непридумается, похорошему его у мелкософта надо выпрашивать.

Это еще зачем? Надо guid - нажимаем ctrl+shift+g что в Lazarus, что в Delphi и все.
Ответить