我正在尝试创建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的东西)中提取了这部分代码的很大一部分.我不希望这段代码能够正常工作,但我不明白为什么它不能编译.
谢谢.
奇怪的是,尽管在这里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;}
除了Eric Melski的回答(因为你说你是初学者,我认为他的答案对你来说并不清楚):
您收到此错误的原因是因为AudioEndpointVolumeNotifierImpl是一个抽象类,这意味着它具有纯虚方法,可以直接在类中定义,也可以从基类继承.
在你的情况下,显然是后者.
您要做的是实现您尝试过的继承纯虚方法,但如果方法的签名不相同,您只需定义一个重载,并保持基本纯虚方法不变.你的班级仍然是抽象的.因此错误消息.