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



         

Двунаправленные интерфейсные контракты - часть 11


Кроме этого, в СОМ предусмотрено два интерфейса, которые позволяют средам этапа выполнения запрашивать объект самостоятельно (introspectively) возвращать информацию об импортируемых в него и экспортируемых им типах интерфейсов:

[object,uuid(B196B283-BAB4-101A-B69C-00AA00341D07) ] interface IProvideClassInfo : Unknown { // return description of object's coclass // возвращаем описание кокласса объекта HRESULT GetClassInfo([out] ITypeInfo ** ppTI); }

[object, uuid(A6BC3AC0-DBAA-11CE-9DE3-00M004BB851) ] interface IProvideClassInfo2 : IProvideClassInfo { typedef enum tagGUIDKIND { GUIDKIND_DEFAULT_SOURCE_DISP_IID = 1 } GUIDKIND; // return IID of default outbound dispinterface // возвращаем IID принятого по умолчанию экспортируемого диспинтерфейса HRESULT GetGUID([in] DWORD dwGuidKind, [out] GUID * pGUID); }

Оба этих интерфейса весьма просты для реализации:

STDMETHODIMP Surfboard::GetClassInfo(ITypeInfo **ppti) { assert(ppti != 0); ITypeLib *ptl = 0; HRESULT hr = LoadRegTypeLib(LIBID_BeachLib, 1, 0, 0, &ptl); if (SUCCEEDED(hr)) { hr = ptl->GetTypeInfoOfGuid(CLSID_Surfboard, ppti); ptl->Release(); } return hr; }

STDMETHODIMP Surfboard::GetGUID (DWORD dwKind, GUID *pguid) { if (dwKind != GUIDKIND_DEFAULT_SOURCE_DISP_IID !pguid) return E_INVALIDARG; // ISurfboardUser must be defined as a dispinterface // ISurfboardUser должен быть определен как диспинтерфейс *pguid = IID_ISurfboardUser; return S_OK; }

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

Предположим, что интерфейс ISurfboardUser определен как диспинтерфейс следующим образом:

[uuid(315BC28A-DEA7-11d0-8C5E-0080C73925BA)] dispinterface ISurfboardUser { methods: [id(1)] void OnTiltingForward( [in] long nAmount); [id(2)] void OnTiltingSideways( [in] long nAmount); }

При программировании на Visual Basic можно объявить переменные, понимающие тип интерфейса обратного вызова, принятый по умолчанию, таким образом:




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