Сущность технологии COM



         

Маршалер свободной поточной обработки (FreeThreaded Marshaler) - часть 9


Те методы, которым нужен доступ к глобализованным указателям, могут импортировать локальную копию посредством метода Localize из GlobalInterfaсePointer:

STDMETHODIMP SafeRect::get_Top(long *pVal) { IPoint *pPoint = 0; // local imported pointer // локальный импортированный указатель HRESULT hr = m_gipTopLeft.Localize(&pPoint); if (SUCCEEDED(hr)){ long x; hr = pPoint->get_Coords(&x, pVal); pPoint->Release(); } return hr; }

Отметим, что в силу применения маршалера свободной поточной обработки (FreeThreaded Marshaler) исходный интерфейсный указатель не может быть кэширован, а должен импортироваться при каждом вызове метода, чтобы предотвратить попытку доступа из неверного апартамента.

Предыдущий фрагмент кода может быть автоматизирован еще больше. Поскольку большинство вызовов методов в классе GlobalInterfacePointer должны будут локализовать временный указатель в самом вызове метода, то приводимый ниже класс автоматизирует импорт временного указателя и его последующее освобождение, что очень напоминает интеллектуальный указатель (smart pointer):

template <class Itf, const IID* piid> class LocalInterfacePointer { Itf *m_pItf; // temp imported pointer // временный импортированный указатель // prevent misuse // предотвращаем неверное использование LocalInterfacePointer(const LocalInterfacePointer&); operator = (const LocalInterfacePointer&); public: LocalInterfacePointer(const GlobalInterfacePointer<Itf, piid>& rhs, HRESULT& hr) { hr = rhs.Loca1ize(&m_pItf) ; }

LocalInterfacePointer(DWORD dwCookie, HRESULT& hr) { assert(g_pGIT != 0); hr = g_pGIT-&gtGetInterfaceFromGlobal(dwCookie, *piid, (void**)&m_pItf); }

~LocalInterfacePointer(void) { if (m_pItf) m_pItf->Release(); }

class SafeItf : public Itf { STDMETHOD_(ULONG, AddRef) (void) = 0; // hide // скрытый STDMETHOD_(ULONG, Release)(void) = 0; // hide // скрытый };

SafeItf *GetInterface(void) const { return (SafeItf*) m_pItf; }

SafeItf *operator ->(void) const { assert(m_pItf != 0); return GetInterface(); }




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