Анализатор обнаружил подозрительный вызов оператора 'dynamic_cast' при работе с COM-интерфейсами. При такой работе не увеличивается счётчик количества ссылок на объект, что может привести к попыткам работы с разрушенным объектом или другим проблемам.
Рассмотрим синтетический пример. Допустим, в коде есть COM-интерфейсы 'IDraw' и 'IShape', которые отвечают за работу с некой геометрической фигурой:
interface IDraw : public IUnknown { .... virtual HRESULT Draw() = 0; .... }; interface IShape : public IUnknown { .... virtual HRESULT GetArea(double *area) = 0; .... };
Также у нас есть COM-объект 'Circle', который имплементирует интерфейсы 'IDraw' и 'IShape':
class Circle : public IDraw, public IShape { .... };
Теперь рассмотрим пример неправильной работы с нашим COM-объектом через интерфейс 'IDraw':
void foo(IDraw *ptrIDraw) { IShape *ptrIShape = dynamic_cast<IShape*>(ptrIDraw); .... if (ptrIShape) ptrIShape->GetArea(area); .... }
В примере выше не произойдет увеличение счётчика ссылок на объект типа 'Circle'. Для увеличения и уменьшения счётчика должны зваться функции 'AddRef' и 'Release' соответственно.
Правильным способом работы c COM-интерфейсами будет использование функции 'QueryInterface', которая специально предназначена для этого.
Функция 'QueryInterface' должна:
Таким образом, корректный код выглядит так:
void foo(IDraw *ptrIDraw) { IShape *ptrIShape = nullptr; .... if (SUCCEEDED(ptrIDraw->QueryInterface(IID_IShape, &ptrIShape)) .... }
Данная диагностика классифицируется как: