Динамический массив COM-объектов - PullRequest
2 голосов
/ 23 февраля 2010

У меня есть COM-объект ATL, который должен предоставлять коллекцию других COM-объектов, чтобы клиенты могли узнать, сколько объектов в коллекции (через простое свойство Count, которое я могу предоставить) и получить доступ к объектам, используя его индекс. Эта коллекция объектов является динамической - количество не фиксировано - и я не знаю, сколько будет, когда будет построен мой основной (родительский) объект (поэтому я не могу создать эти объекты, например, в моем FinalConstruct) , Объекты, которые я хочу выставить, имеют свойства только для чтения.

Что я хочу сделать, так это каким-то образом создать std::vector этих объектов при первом использовании. Я хочу использовать интеллектуальные COM-указатели ATL, где это возможно, поэтому мне не нужно вручную управлять количеством ссылок и т. Д., Но я не уверен, следует ли мне использовать CComPtr, 'CComQIPtr' и т. Д.

Предполагая, что объекты, которые я хочу вернуть, называются IChild, я надеялся, что смогу сделать что-то вроде этого:

std::vector<CComPtr<IChild> > children;
...
CComPtr<IChild> child;
// Somehow instantiate an IChild?
...
children.push_back(child);

STDMETHODIMP Parent::GetAt(LONG index, IChild** pRet)
{
  *pRet = children[index];
}

Если у кого-нибудь есть указания на то, как мне этого добиться, я был бы очень рад. Есть отличная статья о том, как обнажить статический объект , но я не могу найти ничего о конкретной проблеме.

Ответы [ 2 ]

6 голосов
/ 24 февраля 2010

Да, std::vector< CComPtr<IChild> > - это способ сделать это - вы получите динамический массив IChild*, который управляет временем жизни IChild -приобретенных объектов.Как только вы захотите преобразовать IChild* в производный интерфейс, вам придется использовать QueryInterface() так же, как вы бы использовали dynamic_cast с объектами C ++.

Нет смысла использовать CComQIPtrдля массива.Основное использование CComQIPtr - это удобный способ вызова QueryInterface() для указателя на объект, который, возможно, реализует интересующий интерфейс.Вместо вызова QueryInterface() и проверки результата вы вызываете конструктор CComQIPtr и проверяете, содержит ли результирующий объект ненулевой указатель.Вы можете использовать CComQIPtr в коде, который использует ваш массив, но нет смысла использовать его для самого массива.

2 голосов
/ 23 февраля 2010

CComPtr<...> предполагает, что вы назначаете ему совместимый интерфейс. CComQIPtr<...> вызывает IUnknown::QueryInterface, чтобы получить правильный интерфейс. Поэтому в качестве параметра шаблона требуется дополнительный GUID.

Для ваших целей вам следует использовать CComPtr, поскольку вы знаете, что всегда будете инициализировать записи с IChild.

...