Question

I am trying to create a class that implements the IUnknown interface. I have the following code in the header file:

#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);
};  

I have included the relevant uuid.lib and several others. However, when I attempt to compile, I get the error:

Error 2 error LNK2001: unresolved external symbol "public: virtual long __stdcall Vmr9Presenter::QueryInterface(struct _GUID const &,void * *)" (?QueryInterface@Vmr9Presenter@@UAGJABU_GUID@@PAPAX@Z) Vmr9Presenter.obj VmrPresenter

This leads me to believe that something isn't getting pulled in. Any suggestions on how to get rid of this error?

Was it helpful?

Solution

All the I* interfaces are just that - interface definitions. An interface is a pure virtual base class in C++ terms.

When you say:

class Vmr9Presenter : IVMRImagePresenter9, IVMRSurfaceAllocator9

you're saying "the Vmr9Presenter class implements these interfaces". You're also saying "The Vmr9Presenter class derives from two pure virtual base classes named IVMRImagePresenter9 and IVMRSurfaceAllocator9. By convention all interfaces derive from a pure virtual base class called IUnknown.

This means that you need to implement all the methods in the pure virtual base classes in your object. So you need to implement all the methods on IVMRImagePresenter9 and IVMRSurfaceAllocator9. You ALSO need to implement all the methods on their base classes, including IUnknown.

IUnknown has 3 methods: AddRef, Release and QueryInterface. The error you're reporting says that the linker was unable to find a function named Vmr9Presenter::QueryInterface.

You need to add such a function to your class, once you do that it should work.

Typically a QI implementation looks like:

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;
    }
}

OTHER TIPS

Do either of IVMRImagePresenter9, IVMRSurfaceAllocator9 already implement IUnknown? Maybe you need:

class Vmr9Presenter : IVMRImagePresenter9, IVMRSurfaceAllocator9, IUnknown

I would guess you may also need to implement AddRef() and Release() too according to the docs for IUnknown.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top