【问题标题】:Why CoCreateInstance can return two different HRESULT in the exact same context?为什么 CoCreateInstance 可以在完全相同的上下文中返回两个不同的 HRESULT?
【发布时间】:2019-07-15 12:30:47
【问题描述】:

我想在我的一个应用程序中使用DSound Audio Render,所以我用CoCreateInstance 加载它。根据my previous question,如果我没有安装音频硬件,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,因此它与the answer 一致我在上一个问题中得到,但第二个错误代码0x80040256 对应于VFW_E_NO_AUDIO_HARDWARE。根据MSDN

VFW_E_NO_AUDIO_HARDWARE
0x80040256

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

那么为什么我第二次调用CoCreateInstance 时才出现有意义的错误?在第一次调用时我可以更改什么来出现此错误?

【问题讨论】:

  • 你不应该覆盖 ptr 而不先释放它。您是否尝试在第二次调用 CoCreateInstance 之前添加 ptr->Release()?不确定它是否相关,因为我无法重现您的问题。
  • @SimonMourier 在这种情况下没用,因为发生错误时 ptr 为 NULL。但是,你是对的,它更安全。
  • @SimonMourier 要重现它,您应该在 Windows 的设备管理器中禁用所有音频设备。
  • 它本来可以做得更好,但既然你不应该直接CoCreateInstance 这无论如何它都不是一个错误。我很确定设备枚举器的行为将是一致的并且如文档所述。

标签: c++ com directshow


【解决方案1】:

如果您想要记录和一致的行为,那么您不应该偷工减料并遵循建议的路线,即: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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-20
    • 1970-01-01
    • 2017-09-16
    • 1970-01-01
    • 2018-03-11
    相关资源
    最近更新 更多