我想在我的一个应用程序中使用DSound Audio Render,所以我用CoCreateInstance加载了它。这是一个小片段:
#include <iostream>
#include <strmif.h>
#include <uuids.h>
int main()
{
std::cout << "Start" << std::endl;
HRESULT hr = CoInitialize(NULL);
printf("CoInitialize = 0x%x\n", hr);
IBaseFilter* ptr = NULL;
hr = CoCreateInstance(CLSID_DSoundRender, NULL, CLSCTX_INPROC, IID_IBaseFilter, (void**)&ptr);
printf("CoCreateInstance = 0x%x\n", hr);
ptr->Release();
CoUninitialize();
std::cout << "End" << std::endl;
std::cin.get();
}
问题是,在我用来开发应用程序的Windows上,它运行良好,并且hr
始终为0x0
(S_OK
),但是在我的客户端的Windows上,调用0x0x80040154
时出现错误REGDB_E_CLASSNOTREG
(CoCreateInstance
)。
这是一个在Windows 10 64位(对于开发人员)和Windows Server 2016 Datacenter 64位(对于产品)上运行的32位应用程序。
我检查注册表,并且相应的DLL(quartz.dll
)已正确注册。确实,我在两个Windows上都得到了这些结果:
PS C:\Users\pierre> Get-ChildItem -Path "Registry::HKCR\CLSID\{79376820-07D0-11CF-A24D-0020AFD79767}"
Hive: HKCR\CLSID\{79376820-07D0-11CF-A24D-0020AFD79767}
Name Property
---- --------
InprocServer32 (default) : C:\Windows\System32\quartz.dll
ThreadingModel : Both
PS C:\Users\pierre> Get-ChildItem -Path "Registry::HKCR\WOW6432Node\CLSID\{79376820-07D0-11CF-A24D-0020AFD79767}"
Hive: HKCR\WOW6432Node\CLSID\{79376820-07D0-11CF-A24D-0020AFD79767}
Name Property
---- --------
InprocServer32 (default) : C:\Windows\SysWOW64\quartz.dll
ThreadingModel : Both
PS C:\Users\pierre> dir C:\Windows\System32\quartz.dll
Répertoire : C:\Windows\System32
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 15/09/2018 09:29 1639424 quartz.dll
PS C:\Users\pierre> dir C:\Windows\SysWOW64\quartz.dll
Répertoire : C:\Windows\SysWOW64
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 15/09/2018 09:29 1470464 quartz.dll
我还使用了procmon.exe
,每次通话看起来都是正确的。
我应该更改客户端的配置以使其起作用吗?
答案 0 :(得分:2)
MSDN explains在“备注”部分下,该DirectShow过滤器应如何参与DirectShow图形管道:
此过滤器用作音频设备的包装器。要枚举用户系统上可用的音频设备,请使用ICreateDevEnum接口和音频渲染器类别(CLSID_AudioRendererCategory)。对于每个音频设备,音频渲染器类别包含两个过滤器实例。其中一个对应于DirectSound Renderer,另一个对应于Audio Renderer(WaveOut)过滤器。 DirectSound实例的友好名称为“ DirectSound:DeviceName”,其中DeviceName是设备的名称。 WaveOut实例的友好名称为DeviceName。
请注意,通常不应该直接使用CoCreateInstance
实例化过滤器,这是在做什么。这样做有一个很好的理由:它是一个包装对象,通常需要将其绑定到特定的音频输出设备的初始化上下文。通过直接初始化,您隐式指示其使用默认设备。
在没有音频输出设备的系统上,过滤器将看不到任何设备,并且可能会在早期实例化步骤中发出故障,从而导致COM错误。您会看到COM注册,但是没有硬件和早期故障会触发一般的COM错误,而不是特定于API。
通常,您仍然应该使用ICreateDevEnum
界面(如MSDN建议)而不是CoCreateInstance
。