Вход/Регистрация
Сущность технологии СОМ. Библиотека программиста
вернуться

Бокс Дональд

Шрифт:

Чтобы реализовать управляемый таблицей QueryInterface, необходимо сначала определить, что эта таблица будет содержать. Как минимум, каждый элемент таблицы должен содержать указатель на IID и некое дополнительное состояние, которое позволит реализации найти указатель vptr объекта для запрошенного интерфейса. Хранение указателя функции в каждом элементе таблицы придаст этому способу максимальную гибкость, так как это даст возможность добавлять новые методики поиска интерфейсов к обычному вычислению смещения, которое используется для приведения к базовому классу. Исходный код в приложении к данной книге содержит заголовочный файл inttable.h , который определяет элементы таблицы интерфейсов следующим образом:

// inttable.h (book-specific header file)

// inttable.h (заголовочный файл, специфический для этой книги)

// typedef for extensibility function

// typedef для функции расширяемости

typedef HRESULT (*INTERFACEFINDER) (void *pThis, DWORD dwData, REFIID riid, void **ppv);

// pseudo-function to indicate entry is just offset

// псевдофункция для индикации того, что запись просто

// является смещением

#define ENTRYISOFFSET INTERFACEFINDER(-1)

// basic table layout // представление базовой таблицы

typedef struct INTERFACEENTRY

{

const IID * pIID;

// the IID to match

// соответствующий IID

INTERFACEFINDER pfnFinder;

// функция finder DWORD dwData;

// offset/aux data

// данные по offset/aux

} INTERFACEENTRY;

Заголовочный файл также содержит следующие макросы для создания интерфейсных таблиц внутри определения класса:

// Inttable.h (book-specific header file)

// Inttable.h (заголовочный файл, специфический для данной книги)

#define BASEOFFSET(ClassName, BaseName) \ (DWORD(staticcast<BaseName*>(reinterpretcast\ <ClassName*>(0x10000000))) – 0х10000000)

#define BEGININTERFACETABLE(ClassName) \ typedef ClassName ITCls;\ const INTERFACEENTRY *GetInterfaceTable(void) {\ static const INTERFACEENTRY table [] = {\

#define IMPLEMENTSINTERFACE(Itf) \ {&IID##Itf,ENTRYISOFFSET,BASEOFFSET(ITCls,Itf)},

#define IMPLEMENTSINTERFACEAS(req, Itf) \ {&IID##req,ENTRYISOFFSET, BASEOFFSET(ITCls, Itf)},

#define ENDINTERFACETABLE \ { 0, 0, 0 } }; return table; }

Все, что требуется, – это стандартная функция, которая может анализировать интерфейсную таблицу в ответ на запрос QueryInterface. Такая функция содержится в файле Inttable.h:

// inttable.cpp (book-specific source file)

// inttable.h (заголовочный файл, специфический для данной книги)

HRESULT InterfaceTableQueryInterface(void *pThis, const INTERFACEENTRY *pTable, REFIID riid, void **ppv)

{

if (InlineIsEqualGUID(riid, IIDIUnknown))

{

// first entry must be an offset

// первый элемент должен быть смещением

*ppv = (char*)pThis + pTable->dwData;

((Unknown*) (*ppv))->AddRef ;

// A2

return SOK;

} else

{

HRESULT hr = ENOINTERFACE;

while (pTable->pfnFinder)

{

// null fn ptr == EOT

if (!pTable->pIID || InlineIsEqualGUID(riid,*pTable->pIID))

{

if (pTable->pfnFinder == ENTRYISOFFSET)

  • Читать дальше
  • 1
  • ...
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: