如何使用 WRL ComPtr 初始化 WinRT AudioGraphSettings?
How to initialize WinRT AudioGraphSettings using WRL ComPtr?
使用 C++/WinRT,AudioGraphSettings
可以使用其构造函数轻松初始化:
AudioGraphSettings settings(AudioRenderCategory::Media);
我无法在我的 WRL 项目中使用它。下面是我的实现
ComPtr<IAudioGraphSettings> settings;
Windows::Foundation::GetActivationFactory(
HStringReference(RuntimeClass_Windows_Media_Audio_AudioGraphSettings).Get(),
&settings
);
settings
仍然为 null,我不知道如何使用所需的 AudioRenderCategory
构造函数对其进行初始化。
如果我像下面那样做,我会遇到访问冲突崩溃,因为它仍然是空的。
settings->put_AudioRenderCategory(AudioRenderCategory::AudioRenderCategory_Media);
ABI 级别的类型激活比在 C++ 中实例化类型等更复杂。公认的简洁 documentation 概述了不同的机制:
WinRT defines three activation mechanisms: direct activation (with no constructor parameters), factory activation (with one or more constructor parameters), and composition activation.
IAudioGraphSettings
类型属于第二类:它根据 AudioRenderCategory
类型的单个参数实例化一个类型。因此实例化类型是一个 two-phase 过程:
- 检索激活工厂
- 使用激活工厂实例化一个类型
问题中的代码将两个操作混为一谈,调用 GetActivationFactory
returns 一个 HRESULT
值 0x80004002,即 E_NOINTERFACE
。它需要改为请求 IAudioGraphSettingsFactory
接口,然后使用该工厂实例化 IAudioGraphSettings
类型。
以下是一个完整的实现,说明了如何激活 IAudioGraphSettings
类型:
#include <wrl/wrappers/corewrappers.h>
#include <wrl/client.h>
#include <windows.foundation.h>
#include <windows.media.audio.h>
#include <windows.media.render.h>
#pragma comment(lib, "windowsapp")
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::Media::Audio;
using namespace ABI::Windows::Media::Render;
int main()
{
RoInitializeWrapper init { RO_INIT_MULTITHREADED };
HRESULT hr { init };
if (FAILED(hr))
return hr;
// Retrieve activation factory
ComPtr<IAudioGraphSettingsFactory> settings_factory {};
hr = GetActivationFactory(
HStringReference(RuntimeClass_Windows_Media_Audio_AudioGraphSettings).Get(),
&settings_factory);
if (FAILED(hr))
return hr;
// Use activation factory to instantiate type
ComPtr<IAudioGraphSettings> settings {};
hr = settings_factory->Create(AudioRenderCategory_Media, &settings);
if (FAILED(hr))
return hr;
return hr;
}
这就是 ABI 级别的情况,ABI 级别最终是 WRL 所在的位置。 C++/WinRT 处理所有样板代码,并将参数化工厂激活巧妙地映射到 C++ 构造函数实现上。这就是 C++/WinRT 实现如此紧凑的原因。
使用 C++/WinRT,AudioGraphSettings
可以使用其构造函数轻松初始化:
AudioGraphSettings settings(AudioRenderCategory::Media);
我无法在我的 WRL 项目中使用它。下面是我的实现
ComPtr<IAudioGraphSettings> settings;
Windows::Foundation::GetActivationFactory(
HStringReference(RuntimeClass_Windows_Media_Audio_AudioGraphSettings).Get(),
&settings
);
settings
仍然为 null,我不知道如何使用所需的 AudioRenderCategory
构造函数对其进行初始化。
如果我像下面那样做,我会遇到访问冲突崩溃,因为它仍然是空的。
settings->put_AudioRenderCategory(AudioRenderCategory::AudioRenderCategory_Media);
ABI 级别的类型激活比在 C++ 中实例化类型等更复杂。公认的简洁 documentation 概述了不同的机制:
WinRT defines three activation mechanisms: direct activation (with no constructor parameters), factory activation (with one or more constructor parameters), and composition activation.
IAudioGraphSettings
类型属于第二类:它根据 AudioRenderCategory
类型的单个参数实例化一个类型。因此实例化类型是一个 two-phase 过程:
- 检索激活工厂
- 使用激活工厂实例化一个类型
问题中的代码将两个操作混为一谈,调用 GetActivationFactory
returns 一个 HRESULT
值 0x80004002,即 E_NOINTERFACE
。它需要改为请求 IAudioGraphSettingsFactory
接口,然后使用该工厂实例化 IAudioGraphSettings
类型。
以下是一个完整的实现,说明了如何激活 IAudioGraphSettings
类型:
#include <wrl/wrappers/corewrappers.h>
#include <wrl/client.h>
#include <windows.foundation.h>
#include <windows.media.audio.h>
#include <windows.media.render.h>
#pragma comment(lib, "windowsapp")
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::Media::Audio;
using namespace ABI::Windows::Media::Render;
int main()
{
RoInitializeWrapper init { RO_INIT_MULTITHREADED };
HRESULT hr { init };
if (FAILED(hr))
return hr;
// Retrieve activation factory
ComPtr<IAudioGraphSettingsFactory> settings_factory {};
hr = GetActivationFactory(
HStringReference(RuntimeClass_Windows_Media_Audio_AudioGraphSettings).Get(),
&settings_factory);
if (FAILED(hr))
return hr;
// Use activation factory to instantiate type
ComPtr<IAudioGraphSettings> settings {};
hr = settings_factory->Create(AudioRenderCategory_Media, &settings);
if (FAILED(hr))
return hr;
return hr;
}
这就是 ABI 级别的情况,ABI 级别最终是 WRL 所在的位置。 C++/WinRT 处理所有样板代码,并将参数化工厂激活巧妙地映射到 C++ 构造函数实现上。这就是 C++/WinRT 实现如此紧凑的原因。