ПРОГРАМИРУЕМ 3D ГРАФИКУ ИСПОЛЬЗУЯ DirectX



         

Введение - часть 6


В СОМ-объектах используется таблица указателей на их функции, которая обычно называется v-таблицей (vtable). Аналогичный механизм задействован и в C++ для реализации виртуальных функций класса. Подобно тому, как функции

14 Введение

C++ вызываются из программы на С ценой минимальных дополнительных усилий, можно обращаться к интерфейсам СОМ-объектов из программы на С. Работа с интерфейсами СОМ-объектов из программы на С облегчается тем, что она происходит аналогично работе с функциями классов C++. Фрагмент программы на С, в котором встречается обращение к интерфейсу СОМ-объекта, выглядит следующим образом:

pInterface->lpVtbl->Member(pinterface, argi) ;

А вот как выглядит тот же самый фрагмент в программе на C++:

pInterface->Member(argi) ;

Для определения «срока жизни» СОМ-объектов используются счетчики обращений. Когда на СОМ-объект не остается ни одной ссылки, он сам себя уничтожает. Этот простой механизм заметно облегчает совместное использование СОМ-объектов и освобождает программиста от разнообразных хлопот по управлению данными. Тем не менее это означает, что для правильного использования объектов вы должны представлять себе работу механизма подсчета ссылок.

По сути дела каждый раз, когда СОМ-объект возвращает вам указатель на один из своих интерфейсов, он наращивает значение своего счетчика обращений. Копируя указатель на интерфейс, необходимо нарастить значение счетчика обращений вызовом функции AddRef. После завершения работы с указателем следует вызвать функцию Release данного интерфейса, чтобы уменьшить значение счетчика обращений. На самом деле этим дело не ограничивается, но основная суть именно такова. Приведу фрагмент программы на C++, который получает указатель на интерфейс СОМ-объекта, вызывает функцию интерфейса и затем освобождает его:

pinterface = GetSomeCOMInterface() ;

pInterface->CallMember() ;

p!nterface->Release() ;

Обратите внимание на то, что после вызова Release значением указателя пользоваться уже нельзя, так как объект, на который он ссылается, может оказаться уничтоженным (если вы освободили последнюю или единственную копию объекта). Обычно после вызова Release я присваиваю указателю значение NULL, чтобы облегчить поиск программных ошибок — например, попыток использования недопустимого указателя па интерфейс. Если вы любите макросы (лично я их не люблю), то всегда можете создать макрос RELEASE, который вызывает функцию Release и присваивает указателю значение NULL:




Содержание  Назад  Вперед