Реализация IUnknown, неразрешенный внешний символ
Я пытаюсь создать класс, который реализует IUnknown
интерфейс. У меня есть следующий код в заголовочном файле:
#pragma once
#include "stdafx.h"
#include "Unknwn.h"
class Vmr9Presenter : IVMRImagePresenter9, IVMRSurfaceAllocator9
{
public:
Vmr9Presenter(void);
HRESULT Initialize(void);
~Vmr9Presenter(void);
STDMETHODIMP QueryInterface(const IID &riid, void **ppvObject);
};
Я включил соответствующие uuid.lib
и несколько других. Однако, когда я пытаюсь скомпилировать, я получаю сообщение об ошибке:
Ошибка 2 ошибка LNK2001: неразрешенный внешний символ "public: virtual long __stdcall Vmr9Presenter::QueryInterface(struct _GUID const &,void * *)" (?QueryInterface@Vmr9Presenter@@UAGJABU_GUID@@PAPAX@Z) VmrjrerererePre
Это заставляет меня верить, что что-то не получается. Есть предложения, как избавиться от этой ошибки?
2 ответа
Все интерфейсы I* - это только определения интерфейсов. Интерфейс - это чистый виртуальный базовый класс в терминах C++.
Когда ты сказал:
class Vmr9Presenter : IVMRImagePresenter9, IVMRSurfaceAllocator9
вы говорите "класс Vmr9Presenter реализует эти интерфейсы". Вы также говорите: "Класс Vmr9Presenter является производным от двух чисто виртуальных базовых классов с именами IVMRImagePresenter9 и IVMRSurfaceAllocator9. По соглашению все интерфейсы наследуются от чисто виртуального базового класса с именем IUnknown.
Это означает, что вам нужно реализовать все методы в чисто виртуальных базовых классах вашего объекта. Поэтому вам необходимо реализовать все методы для IVMRImagePresenter9 и IVMRSurfaceAllocator9. Вам также необходимо реализовать все методы на их базовых классах, включая IUnknown.
IUnknown имеет 3 метода: AddRef, Release и QueryInterface. Ошибка, о которой вы сообщаете, говорит о том, что компоновщик не смог найти функцию с именем Vmr9Presenter::QueryInterface.
Вам нужно добавить такую функцию в ваш класс, как только вы это сделаете, она должна работать.
Обычно реализация QI выглядит следующим образом:
HRESULT IVmr9Presenter::QueryInterface(REFIID iid, PVOID *pvInterface)
{
if (pvInterface == NULL)
{
return E_POINTER;
}
*pvInterface = NULL;
if (iid == IID_IUnknown)
{
*pvInterface = static_cast<PVOID>(static_cast<IUnknown *>(this));
return S_OK;
}
if (iid == IID_IVMRSurfaceAllocator9)
{
*pvInterface = static_cast<PVOID>(static_cast<IVMRSurfaceAllocator9*>(this));
return S_OK;
}
:
else
{
return E_NOINTERFACE;
}
}
У любого из IVMRImagePresenter9, IVMRSurfaceAllocator9 уже есть IUnknown? Может быть, вам нужно:
class Vmr9Presenter : IVMRImagePresenter9, IVMRSurfaceAllocator9, IUnknown
Я думаю, вам также может понадобиться реализовать AddRef() и Release() в соответствии с документами для IUnknown.