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

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

// A2

hr = SOK;

break;

} else

{

hr = pTable->pfnFinder(pThis, pTable->dwData, riid, ppv);

if (hr == SOK) break;

}

}

pTable++;

}

if (hr!= SOK)

*ppv = 0;

return hr;

}

}

Получив указатель на запрошенный объект, InterfaceTableQueryInterface сканирует таблицу в поисках элемента, соответствующего запрошенному IID, и либо добавляет соответствующее смещение, либо вызывает соответствующую функцию. Приведенный выше код использует усовершенствованную версию IsEqualGUID, которая генерирует несколько больший код, но результаты по скорости примерно на 20-30 процентов превышают данные по существующей реализации, которая не управляется таблицей. Поскольку код для InterfaceTableQueryInterface появится в исполняемой программе только один раз, это весьма неплохой компромисс.

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

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

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

// AUTOLONG is just a long that constructs to zero

// AUTOLONG – это просто long, с конструктором,

// устанавливающим значение в О

struct AUTOLONG

{

LONG value;

AUTOLONG (void) : value (0) {}

};

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату