![]() |
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]() ![]() ![]() |
|
skyboy |
|
|||
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 4 Всего: 260 |
есть код:
Проблема в том, что применение supports(функция, применяемая для определения, поддерживает ли объект указанный интерфейс) вызывается деструктор объекта. Решил было, что это каким-то боком связано с управляемым временем жизни интерфейсов(я про тот механизм подсчета ссылок, который позволяет удалить объект, когда никто на него не ссылается), потому создал свой класс TInterfacedObjectEx, где перекрыл метод подсчета ссылок, чтоб объект не удалялся в зависимости от количества ссылок. Но это не помогло. Объясните, пожалуйста, почему удаляется объект. |
|||
|
||||
pseud |
|
||||
![]() Экспёрт Тыдыщ ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1175 Регистрация: 18.5.2007 Где: Минск, Беларусь Репутация: 10 Всего: 40 |
В твоем случае используется 3й перегруженный метод. Соответственно ему нужен параметр TClass. А ты подсовываешь TObject. Раз с (.ClassType) все работает ОК. То и пусть работает. Может я чего не допонял... -------------------- Испытание чужого терпения можно считать успешным, если оно лопнуло... |
||||
|
|||||
MetalFan |
|
|||
![]() Аццкий Сотона ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3815 Регистрация: 2.10.2006 Где: Moscow Репутация: 62 Всего: 128 |
хм... а не проще:
1) вместо TObjectList - TInterfaceList 1) вместо Supports и кучи as'ов вызывать QueryInterface -------------------- There are always someone smarter than you... |
|||
|
||||
skyboy |
|
||||
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 4 Всего: 260 |
а вот и не угадал. полный список:
в моем случае используется способ №5. а ошибка возникает при обращении к уже удаленному объекту(о чем я писал); если бы не совпадал тип аргументов - была бы ошибка времени компиляции ;) нуууу.... Мне не надо решение "чтоб только работало". я прошу объяснить причины столь непонятного для меня поведения программы ![]()
Я не буквоед. Но такое предупреждение с чем-то связано ведь, правда? ![]() Да и потом - кода будет столько же. Просто проверка будет не результат вызова supports, а результат отработки queryinterface. На одно приведение "as" будет меньше, но и только ![]() Учитывая, что в реализации supports напрямую используется queryInterface, не думаю, что замена "шила на мыло" радикально изменит ситуацию. но все равно спасибо. |
||||
|
|||||
Shaggy |
|
||||||||
![]() Новичок Профиль Группа: Участник Сообщений: 37 Регистрация: 2.5.2007 Где: г.Ижевск Репутация: 3 Всего: 5 |
нет, используется 4 вариант
если раскомментировать ClassType, 5 вариант
Добавлено через 14 минут и 19 секунд в твоём случае, или дописать так:
или
|
||||||||
|
|||||||||
skyboy |
|
|||
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 4 Всего: 260 |
да. ошибся. мне показалось, что их всего шесть. странно. я же описал класс TInterfacedObjectEx... A, понятно, я сделал перекрывающие методы _addRef и _release не-динамическими. Ок. Объявляем эти методы виртуальными - и все работает. вот немного доработанный вариант:
проблема осталась, хотя, судя по breakpoint'ам, выполняются мой _addRef, а _release выполняется от TINterfacedObject. Почему, подскажите, пожалуйста ![]() Добавлено через 5 минут и 52 секунды в смысле - не валится с криками об ошибке. но объекты все равно уничтожаются до завершения работы программы. |
|||
|
||||
MetalFan |
|
|||
![]() Аццкий Сотона ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3815 Регистрация: 2.10.2006 Где: Moscow Репутация: 62 Всего: 128 |
в классе TInterfacedObject методы _AddRef и _Release не виртуальные, а соответственно не могут быть перекрыты в потомках...
в нем жестко зашит механизм подсчета ссылок. соотв. для реализации своего механизма необходимо реализовать в своем классе методы интерфейса IInterface (aka IUnknown). но в этом случае память придется освобождать ручками.... Это сообщение отредактировал(а) MetalFan - 23.5.2007, 13:33 -------------------- There are always someone smarter than you... |
|||
|
||||
skyboy |
|
|||
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 4 Всего: 260 |
реализовал ![]() Вот только: 1. Методы и прям невиртуальные :( но 2. В коде supports не нашел приведения к TInterfacedObject. Наверное, просто плохо смотрел. Ладно, я думал, тут я какое-то очевидное упущение допустил, а, видимо, просто "так оно реализовано". Ну, что же, обойдусь костылями. |
|||
|
||||
MetalFan |
|
||||
![]() Аццкий Сотона ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3815 Регистрация: 2.10.2006 Где: Moscow Репутация: 62 Всего: 128 |
мда... ладно, подойду с другой стороны: тебе необходимо реализовать АНАЛОГ TInterfacedObject, но со своим механизмом подсчета ссылок. так понятно? не наследника от TInterfacedObject, а именно аналог. p.s.
а зачем оно нужно? там идет работа с интерфейсами... Это сообщение отредактировал(а) MetalFan - 23.5.2007, 23:12 -------------------- There are always someone smarter than you... |
||||
|
|||||
skyboy |
|
|||
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 4 Всего: 260 |
я думал, что если необходимо привести к типу - интерфейсу объект, то делается так: 1. определяются сигнатуры методов, которые декларирует интерфейс. 2. ищутся виртуальные методы с такими сигнатурами(в queryInterface VMTOffset понатыкано - думал для этого) 3. в случае "ненахождения" виртуальных ищутся не-виртуальные методы начиная с класса объекта и вверх по иерархии наследования. но, видимо, механизм работает так: 1. ищет по иерархии наследования класс, который непосредственно объявлен реализатором интерфейса. 2. использует методы этого класса - и, если методы виртуальные в нем, то будет-таки обращение к VMT, если же не-виртуальные, то возьмутся методы этого самого класса... Так, что ли? Добавлено через 5 минут и 6 секунд да. кажется, я прав. по крайней мере, если в моем первом примере "TBar = class(TinterfacedObjectEx, IFoo)" изменить на "TBar = class(TinterfacedObjectEx, IFoo, IInterface)" - т.е. указать явную реализацию интерфейса классом, то все работает. Больше ничего не менял - так и оставил наследование от TInterfacedObject(чесно говоря, лень писать QueryInterface, а copy-paste'ить религия не позволяет ![]() Вот только неясна мотивация к ТАКОЙ "религии" работы с интерфейсами(я имею в виду свою гипотезу, если она не абсурдна) - почему бы не искать методы, начиная с класса объекта и вверх по предкам? |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Delphi: Общие вопросы" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |