我正在尝试创建IAudioEvents COM接口的具体实例(在Vista及更高版本中可用)。这是我第一次涉足COM编程,所以我可能只是在做一些愚蠢的事情。无论如何,以下代码无法使用“C2259:'AudioEndpointVolumeNotifierImpl'进行编译:无法实例化抽象类”。
Class Definiton(AudioEndpointVolumeNotifierImpl.h):
class AudioEndpointVolumeNotifierImpl : public IAudioSessionEvents
{
private:
LONG _cRef;
public:
AudioEndpointVolumeNotifierImpl() : _cRef(1){}
~AudioEndpointVolumeNotifierImpl(){}
HRESULT STDMETHODCALLTYPE OnSimpleVolumeChanged(float NewVolume, BOOL NewMute,LPCGUID EventContext);
HRESULT STDMETHODCALLTYPE OnChannelVolumeChanged(DWORD ChannelCount, float NewChannelVolumeArray[], DWORD ChangedChannel, LPCGUID EventContext){return S_OK;}
HRESULT STDMETHODCALLTYPE OnDisplayNameChanged(LPCWSTR NewDisplayName, LPCGUID EventContext){return S_OK;}
HRESULT STDMETHODCALLTYPE OnGroupingParamChanged(LPCGUID NewGroupingParam, LPCGUID EventContext){return S_OK;}
HRESULT STDMETHODCALLTYPE OnIconPathChanged(LPWCHAR NewIconPath, LPCGUID EventContext){return S_OK;}
HRESULT STDMETHODCALLTYPE OnSessionDisconnected(AudioSessionDisconnectReason DisconnectReason){return S_OK;}
HRESULT STDMETHODCALLTYPE OnStateChanged(AudioSessionState NewState){ return S_OK; }
ULONG STDMETHODCALLTYPE AddRef()
{
return InterlockedIncrement(&_cRef);
}
ULONG STDMETHODCALLTYPE Release()
{
ULONG ulRef = InterlockedDecrement(&_cRef);
if (0 == ulRef)
{
delete this;
}
return ulRef;
}
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, VOID **ppvInterface)
{
if (IID_IUnknown == riid)
{
AddRef();
*ppvInterface = (IUnknown*)this;
}
else if (__uuidof(IAudioSessionEvents) == riid)
{
AddRef();
*ppvInterface = (IAudioSessionEvents*)this;
}
else
{
*ppvInterface = NULL;
return E_NOINTERFACE;
}
return S_OK;
}
};
对应的.cpp:
HRESULT STDMETHODCALLTYPE AudioEndpointVolumeNotifierImpl::OnSimpleVolumeChanged(float NewVolume, BOOL NewMute, LPCGUID EventContext)
{
PostStatusChange(NewVolume);
return S_OK;
}
在以下代码的IClassFactory实例中失败:
...
AudioEndpointVolumeNotifierImpl* pObject = new AudioEndpointVolumeNotifierImpl();
if (pObject == NULL)
{
return E_OUTOFMEMORY ;
}
...
这段代码的很大一部分来自一些教程(特别是IUnknown的东西)。我不希望这段代码能够正常工作,但我不明白为什么它不能编译。
感谢。
答案 0 :(得分:8)
奇怪的是,尽管此处OnIconPathChanged
被描述为采用LPWCHAR
参数:
http://msdn.microsoft.com/en-us/library/dd370939(VS.85).aspx
此处示例中显示LPCWSTR
:
http://msdn.microsoft.com/en-us/library/dd370797(VS.85).aspx
其中一个可能是错的;如果我们假设它是前者,并且该方法实际上采用LPCWSTR
(无论如何在上下文中更有意义),这将解释您的错误。我会尝试将您的声明更改为
HRESULT STDMETHODCALLTYPE OnIconPathChanged(LPCWSTR NewIconPath, LPCGUID EventContext){return S_OK;}
答案 1 :(得分:7)
除了Eric Melski的回答(因为你说你是初学者,我认为他的答案对你来说不太清楚):
您收到此错误的原因是因为AudioEndpointVolumeNotifierImpl是一个抽象类,这意味着它具有纯虚方法,可以直接在类中定义,也可以从基类继承。
在你的情况下,显然是后者。
您要做的是实现您尝试过的继承纯虚方法,但如果方法的签名不相同,您只需定义一个重载,并保持基本纯虚方法不变。你的班级仍然是抽象的。因此错误信息。
答案 2 :(得分:2)
当您收到此错误时,您通常可以在输出控制台(即错误列表)中查找“由于以下成员:”并且您将看到使该类抽象的内容。