![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Объект, вызвавший данный метод? [D6, Win2k]
VaS © (2002-11-18 11:33:00)Как получить указатель на объект, вызвавший данный метод другого объекта?
Конкретно.
Имеем проблему: RefCount > 0 в деструкторе.
Нужно: выяснить в каких местах программы не вызывается Release().
Идея: Отслеживаем, кто вызывает _AddRef(), заносим указатель на него в список. В _Release() ищем в списке такой указатель и удаляем его. Т.е. будут дубликаты указателей на один и тот же объект, удалять будем, соответственно, один из указателей. В деструкторе можно получить список оставшихся указателей. Этого достаточно.
Посмотрел исходник MemCheck. Его функции всегда возвращают в качестве вызывающего (Caller) TBaseClass._AddRef(), что ничего не дает :( (TBaseClass - базовый класс моей иерархии).
Возникло подозрение, что _AddRef() вызывается уже позже QueryInterface() (или as).
Есть идеи?
VaS (2002-11-18 14:00:00) [1]Да, руками пишется IUnknown.
Юрий Федоров (2002-11-18 13:09:00) [2]А как вообще пошел деструктор, если RefCount > 0? Руками его кто-то разрушает что-ли? Или руками пишутся AddRef"ы и Release"ы?
VaS (2002-11-18 13:05:00) [3]up
VaS (2002-11-18 12:05:00) [4]kull: Да, этот момент известен.
VaS (2002-11-18 12:04:00) [5]Стэк получить удалось. Но это не решает проблемы. Невозможно отследить где же не вызывается Release().
kull (2002-11-18 12:02:00) [6]И еще хитрый момент.
procedure DoSomesting(itf: IMyInterface2);
begin
....
end;
....
var
MyInterface: IMyInterface1;
begin
MyInterface := TMyInterface1.Create;
DoSomething(MyInterface as IMyInterface2);
//после этого вызова объект класса TMyInterface1 прекращает
//сущесвование.
end;
Поэтому лучше объявлять:
procedure DoSomesting(const itf: IMyInterface2);
или
procedure DoSomesting(var itf: IMyInterface2);
kull (2002-11-18 11:47:00) [7]Оператор as всегда увеличивает счетчик ссылок.