Я пытаюсь реализовать общую логику с использованием агрегации COM с помощью ATL. Я определил базовый класс , который называется CameraBase
, который доступен только посредством агрегации. Поэтому я добавил аннотацию aggregateable
к ее coclass
-declaration.Являются ли агрегированные объекты вынужденными быть ссылкой IUnknown?
[
uuid(...),
aggregatable
]
coclass CameraBase
{
[default] interface ICamera;
};
Я также добавил DECLARE_ONLY_AGGREGATEABLE
макрос в определение класса.
class ATL_NO_VTABLE CCameraBase :
public CComObjectRootEx<CComMultiThreadModel>,
public CComCoClass<CCameraBase, &CLSID_CameraBase>,
public ISupportErrorInfo,
public IProvideClassInfoImpl<...>,
public IDispatchImpl<...>
{
public:
CCameraBase()
{
}
DECLARE_REGISTRY_RESOURCEID(IDR_CAMERABASE)
DECLARE_ONLY_AGGREGATABLE(CCameraBase)
BEGIN_COM_MAP(CCameraBase)
...
END_COM_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
...
}
Теперь у меня разные классы, которые используют логику CameraBase
где-то. Therefor Я удлинен на ком карту родительского класса (например, SampleCamera
):
BEGIN_COM_MAP(CSampleCamera)
COM_INTERFACE_ENTRY_AGGREGATE(IID_ICamera, m_base)
...
END_COM_MAP
DECLARE_GET_CONTROLLING_UNKNOWN()
Так как я хочу, чтобы иметь возможность вызывать членов на CameraBase
(через интерфейс ICamera
) из родительского класса, я не хотите использовать COM_INTERFACE_ENTRY_AUTOAGGREGATE
, который хранит указатель внутреннего объекта в качестве ссылки IUnknown
. Therefor Я создаю это самостоятельно из FinalConstruct
-метода:
HRESULT FinalConstruct()
{
HRESULT hr;
if (FAILED(hr = m_camera.CoCreateInstance(CLSID_CameraBase, this->GetControllingUnknown(), CLSCTX_INPROC_SERVER)))
return hr;
}
Где m_camera
определяется как CComPtr<ICamera>
. Однако это приводит к ошибке CLASS_E_NOAGGREGATION
(HRESULT 0x80040110
). Мое текущее обходное решение состоит в том, чтобы сохранить две ссылки: IUnknown
и ICamera
, и запрос для более поздней.
if (FAILED(hr = m_base.CoCreateInstance(CLSID_CameraBase, this->GetControllingUnknown(), CLSCTX_INPROC_SERVER)) ||
FAILED(hr = m_base->QueryInterface(&m_camera)))
return hr;
Это работает, но он чувствует себя любопытное странно, так как класс (CameraBase
), которые получают это инстанциирован одинакова в обоих случаях. Я что-то упускаю? Использую ли я правильный способ объединить внутренний объект? Почему возвращаемый указатель CoCreateInstance
должен иметь тип IUnknown
, если передается внешнее неизвестное?
Заранее благодарен! :)
Спасибо за подробный ответ! :) Итак, насколько я понял, я ничего не сделал, и сохранение указателя IUnknown внутреннего объекта, не являющегося делегированием, является требованием соглашения об объединении COM. – Carsten