Release интерфейсов

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

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

Ответить
Аватара пользователя
XProger
новенький
Сообщения: 44
Зарегистрирован: 13.08.2007 02:52:28
Откуда: Москва
Контактная информация:

Release интерфейсов

Сообщение XProger »

Приветствую.
Имеется некий экземпляр интерфейсного типа Tex1.

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

begin
  Tex1 := Render.Material.Texture.Load('map_dxt_gen.xtx');
  Tex1 := Render.Material.Texture.Load('map_dxt_mip5.xtx');
  Tex1 := Render.Material.Texture.Load('test.xtx');
  LogOut('Main Loop: Begin');
end;

Delphi начинает высвобождать все "потерянные" интерфейсы при выходе из процедуры:
+ "map_dxt_gen.xtx"
+ "map_dxt_mip5.xtx"
+ "test.xtx"
Main Loop: Begin
- "map_dxt_mip5.xtx"
- "map_dxt_gen.xtx"

FPC же в свою очередь начинает мудрить:
+ "map_dxt_gen.xtx"
- "map_dxt_gen.xtx"
+ "map_dxt_mip5.xtx"
+ "test.xtx"
Main Loop: Begin
- "map_dxt_mip5.xtx"

Т.е. некоторые объекты в FPC высвобождаются прямо при потере указателя, другие по выходу из процедурки.
Можно ли заставить это дело работать на обоих компиляторах однозначно? )

И ещё вопрос.

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

  Tex1 := Render.Material.Texture.Load('map_dxt_gen.xtx');
  Tex1 := nil;
  Tex1 := Render.Material.Texture.Load('map_dxt_mip5.xtx');
  Tex1 := nil;
  Tex1 := Render.Material.Texture.Load('test.xtx');

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

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

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

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

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

procedure load(const name: string; out tex: IMyInterface);


Совершенно однозначного поведения на обоих компиляторах едва ли можно добиться - разработчики заявляют, что зависимость программы от моментов высвобождения интерфейсов является ошибкой дизайна, и приводить эти моменты в соответствие с Дельфи не намерены. Тем более что в данном случае Дельфи неправ - правильнее высвобождать при перезаписи переменной.
Тем не менее, поведение FPC 2.3.1 несколько ближе к Дельфи (из-за улучшения оптимизатора). В 2.2.2 этот патч не попал.
Аватара пользователя
XProger
новенький
Сообщения: 44
Зарегистрирован: 13.08.2007 02:52:28
Откуда: Москва
Контактная информация:

Сообщение XProger »

Tex1 - поле класса, а сам код выполняется в одном из его методов :)
Про ошибки дизайна это безусловно верно, но хотелось бы максимально предсказуемого поведения )
Аватара пользователя
alexs
долгожитель
Сообщения: 4069
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь
Контактная информация:

Сообщение alexs »

Нефиг.
Не надо чужие ошибки повторять здесь.
Лучше исправит ошибку в своём коде самому, чем заставлять потом мучаться всех с этой "фичей". Проходили уже.
Аватара пользователя
XProger
новенький
Сообщения: 44
Зарегистрирован: 13.08.2007 02:52:28
Откуда: Москва
Контактная информация:

Сообщение XProger »

alexs, вопрос сводится к: как высвободить интерфейс моментально, не дожидаясь завершения работы процедурки. Есть мысли на этот счёт?
Аватара пользователя
*vmr
постоялец
Сообщения: 168
Зарегистрирован: 08.01.2007 00:46:07
Откуда: Киев
Контактная информация:

Сообщение *vmr »

XProger писал(а):Delphi начинает высвобождать все "потерянные" интерфейсы при выходе из процедуры:

Несовсем верно, посмотри дизасм и увидиш что ClearIntf вызываетьмя на каждом Tex1 := nil;
Просто, скорее всего, делфа создала еще один "скрытый" указатель на интерфейс, который и освобождается при выходе из процедуры

Об этой особенности Дельфы уже писал и кидался ссылками где только можно :)
http://community.livejournal.com/ru_delphi/191694.html

Добавлено спустя 1 минуту 19 секунд:
XProger писал(а):вопрос сводится к: как высвободить интерфейс моментально, не дожидаясь завершения работы процедурки. Есть мысли на этот счёт?

Минимизировать кастинг интерфейсов :)
Mirage
энтузиаст
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia
Контактная информация:

Сообщение Mirage »

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

while tex1._Release > 0 do ;
не помогает?

По идее, единственное, что может иметь значение в освобождении интерфейсов это порядок. Он одинаков в обоих случаях.
Хотя автоматическое управление памятью без специальных средств для этого (сборщик мусора), все равно ни к чему хорошему не приводит. Особенно при требованиях кросскомпиляторной/кроссплатформенной совместимости.
Аватара пользователя
*vmr
постоялец
Сообщения: 168
Зарегистрирован: 08.01.2007 00:46:07
Откуда: Киев
Контактная информация:

Сообщение *vmr »

Mirage писал(а):while tex1._Release > 0 do ;
не помогает?

А вот этого не надо!
Даже в МСДН-не не рекомендуют так делать — функция НЕ ОБЯЗАНА возвращать значение (что и наблюдается у многих стандартных интерфейсов)

Даже если этот метод сработает, то получим другой баг — дельфа то ничего не зная о подобных фокусах чесно попытается освободить уже освобоженный интерфейс на выходе из ф-и. Как результат — получим Access Violation

ЗЫ: поведение Дельфы описано в вышеприведенной ссылке
Ответить