为什么CoCreateInstance可以在完全相同的上下文中返回两个不同的HRESULT?

时间:2019-02-21 14:42:23

标签: c++ com directshow

我想在我的一个应用程序中使用DSound Audio Render,所以我用CoCreateInstance加载了它。根据{{​​3}},如果我未安装音频硬件,则CoCreateInstance可以返回REGDB_E_CLASSNOTREG。但是,如果我第二次打电话给CoCreateInstance,则没有相同的HRESULT。这是一个小示例(要重现它,您应该在Windows的设备管理器中禁用所有音频设备):

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

    if(ptr)
        ptr->Release();

    hr = CoCreateInstance(CLSID_DSoundRender, NULL, CLSCTX_INPROC, IID_IBaseFilter, (void**)&ptr);

    printf("CoCreateInstance = 0x%x\n", hr);

    if(ptr)
        ptr->Release();

    CoUninitialize();

    std::cout << "End" << std::endl;

    std::cin.get();
}

我得到这个结果:

Start
CoInitialize = 0x0
CoCreateInstance = 0x80040154
CoCreateInstance = 0x80040256
End

第一个错误代码0x80040154对应于REGDB_E_CLASSNOTREG,因此它与我在上一个问题中遇到的my previous question是一致的,但是第二个错误代码0x80040256对应于{{1 }}。根据{{​​3}}:

  

VFW_E_NO_AUDIO_HARDWARE
  0x80040256

     

无法播放音频流:   没有可用的音频硬件,或者不支持该硬件。

那么,为什么只有第二次致电VFW_E_NO_AUDIO_HARDWARE时才出现有意义的错误?我该如何更改才能在第一次通话时出现此错误?

1 个答案:

答案 0 :(得分:2)

如果您要记录下来并保持一致的行为,则不要走捷径并遵循建议的方针,即Using the System Device Enumerator

枚举音频渲染器类别中的设备将为您提供“默认DirectSound设备”的绰号对象,然后您的IMoniker::BindToObject将产生有意义的VFW_E_NO_AUDIO_HARDWARE(在第一次调用和随后的调用中) 。

您也可以在不编写代码的情况下查看此操作:您可以在组合框中使用GraphStudioNext应用程序,菜单Graph,Insert Filter,“ Audio Renderers”类别,然后双击“ Default DirectSound Device”条目尝试实例化过滤器。

至于关于不同代码的标语问题,这是我的有根据的猜测。错误代码最终来自软件。您有机会看到系统中存在COM服务器,因此COM子系统确实开始实例化,然后在中间失败并向您转发失败代码。 COM服务器可能具有单例或以其他方式缓存的硬件枚举。在您的第一次尝试中,它在初始化过程中达到“无设备”条件,并在较早的步骤中止了实例化,因此COM报告无法创建实例。下次服务器已经看到其缓存的枚举(也就是说,它与您假定的“上下文不完全相同”)并跳过初始故障点时,却再次迷失了下一次检查。

您无能为力,特别是首先应该以不同的方式实例化CLSID_DSoundRender