Интерфейсы DirectX

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

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

Интерфейсы DirectX

Сообщение FedeX »

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

Пытаюсь работать с интерфеёсами 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

Помогите пожалуйста!!! Я так не люблю утечки памяти! :)
Mirage
энтузиаст
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia
Контактная информация:

Сообщение Mirage »

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

Еще при создании интерфейса, если это делать руками, надо сразу вызывать _Release, иначе кол-во ссылок сразу будет равным 2, а не 1.
Например в DirectXGraphics.pas делается так:

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

  Result := IDirect3D8(_Direct3DCreate8(SDKVersion));
  if Result <> nil then Result._Release;


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

Сообщение FedeX »

Да, в принципи слышал я чой-то такое...
О! И в правду если сразе после 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 »

Хотя не-а!.. Постойте...
После 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. Ох уж мне эта самодеятельность!

Вообщем спасибо! :)
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
Сообщения: 1409
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

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

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