Интерфейсы DirectX

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

Интерфейсы DirectX

Сообщение FedeX » 10.10.2006 20:46:55

Помогитя! Замучалси.

Пытаюсь работать с интерфеёсами DirectMusic.
В принципе почти всё получается... Почти, но не всё.

Не могу удалить ни одного интерфейса. Метода Release как в SDK нема. Есть тока _Release. Но он не пашет. Вылетают всякие Acces-ы.

Пробовал убрать совсем _Release. Просто присваиваю всем интерфейсам значение nil. Но при этом, если я, например, удаляю строки
Код: Выделить всё
    m_Performance.Stop(nil,nil,0,0);
    m_Performance.CloseDown;     

а оставляю
Код: Выделить всё
     m_Performance:=nil;

...то если музыка играла, то она и играет, как ни в чём не бывало. Получается что она либо играет без него (главного интерфейса воспроизведения), либо присвоение nil ничего не удаляет.

Ах да использую DirectX 9.0 Delphi / FreePascal adaptation by Alexey Barkovoy из http://clootie.ru. И Lazarus 9.16

Помогите пожалуйста!!! Я так не люблю утечки памяти! :)
Аватара пользователя
FedeX
постоялец
 
Сообщения: 422
Зарегистрирован: 27.03.2006 09:25:34
Откуда: украина, житомир

Сообщение Mirage » 11.10.2006 16:38:08

Надо уметь работать с интерфейсами, прежде всего.
В частности, знать, что для них используется подсчет ссылок.
Просто вызов _Release лишь уменьшает число ссылок на интерфейс (кстати, возвращая это число). Удаление произойдет если число ссылок станет равным нулю.
В данном случае дело скорее всего в том, что где-либо есть ссылка на этот m_Performance. Например - в других интерфейсах DirectMusic. Их надо освобождать в правильной последовательности.

Еще при создании интерфейса, если это делать руками, надо сразу вызывать _Release, иначе кол-во ссылок сразу будет равным 2, а не 1.
Например в DirectXGraphics.pas делается так:
Код: Выделить всё
  Result := IDirect3D8(_Direct3DCreate8(SDKVersion));
  if Result <> nil then Result._Release;


Не работал с DirectMusic - не знаю как там и что, но принцип тот же.
Mirage
энтузиаст
 
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Сообщение FedeX » 11.10.2006 21:13:18

Да, в принципи слышал я чой-то такое...
О! И в правду если сразе после CoCreateInstance(CLSID_DirectMusicPerformance... вызвать MessageBox(parent_window,PChar(inttostr(m_Performance._Release)),nil,0); то выбивает "1". (А чо так? Глюк компилера?).
Или есть какая директива чтоб отключить повторное создание?... А то у меня стоко интерфейсов используется уже, и везде при создании уничтожать...
Да к томуже теперь до последнего _Release даже не доходит - вылетают куча матов в окнах. Ну это, правда, наверное из-за того, что я ещё не для всех других интерфейсов расставил _Release и гдето есть , эти , ссылки.
Аватара пользователя
FedeX
постоялец
 
Сообщения: 422
Зарегистрирован: 27.03.2006 09:25:34
Откуда: украина, житомир

Сообщение FedeX » 11.10.2006 23:16:26

Хотя не-а!.. Постойте...
После CoCreateInstance ещё одна ссылка на m_Performance...
Это после m_Performance.InitAudio их уже две!..
... Причём метод m_Performance.CloseDown (при деинициализации) уменьшает не одну количество ентих ссылок...

Да и в СДК написано (как-то ни глянул):

CloseDown handles the release of the IDirectMusic8 interface if this reference was created by IDirectMusicPerformance8::Init or IDirectMusicPerformance8::InitAudio.

Так что две ссылки - это не глюк... И делать _Release после создания интерфейса не нужно (ф-фу-у - аш легче)

И теперь ясно почему музыка продолжала играть: m_Performance.CloseDown нужно делать обязательно.

И оказалось, что m_Performance:=nil аналогичен m_Performance._Release (проверено тем же MessageBox(parent_window,PChar(inttostr(m_Performance._Release)),nil,0);).

Но в Делфи (и видимо Фри Паскале) правельнее делать nil, потому что, как написано на одном форуме, сам компилер, типа при выходе из программы проверяет все интерфейсы на nil и если они не nil , то делает _Release. Ох уж мне эта самодеятельность!

Вообщем спасибо! :)
Аватара пользователя
FedeX
постоялец
 
Сообщения: 422
Зарегистрирован: 27.03.2006 09:25:34
Откуда: украина, житомир

Сообщение Sergei I. Gorelkin » 12.10.2006 13:15:08

AddRef и Release для того и переименованы в _AddRef и _Release, чтобы подчеркнуть, что их практически никогда не нужно вызывать вручную. Это не Си, компилятор следит за такими вещами сам.
Присвоение интерфейсов (a := b) означает, что будут вызваны b.AddRef (естественно, если b <> nil) и a.Release. Выход переменной из области видимости также приводит к вызову Release.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1395
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград


Вернуться в Графика

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 8

Рейтинг@Mail.ru