如何:使用 WRL 激活和使用 Windows 运行时组件
本文档演示如何使用 Windows 运行时 C++ 模板库 (WRL) 初始化 Windows 运行时,以及如何激活和使用 Windows 运行时组件。
若要使用组件,必须获取指向组件实现的类型的接口指针。 由于 Windows 运行时的基础技术是组件对象模型 (COM),因此必须遵循 COM 规则来维护此类型的实例。 例如,必须维护引用计数,其可以确定何时从内存中删除此类型。
为了简化 Windows 运行时的使用,Windows 运行时 C++ 模板库提供了可以自动执行引用计数的智能指针模板 ComPtr<T>。 声明变量时,请指定ComPtr<
接口名称>
标识符。 若要访问接口成员,请将箭头成员访问运算符 (->
) 应用于标识符。
重要
调用接口函数时,请务必测试 HRESULT 返回值。
激活和使用 Windows 运行时组件
以下步骤使用 Windows::Foundation::IUriRuntimeClass
接口演示如何为 Windows 运行时组件创建激活工厂、创建该组件的实例以及检索属性值。 它们还演示如何初始化 Windows 运行时。 之后提供了完整示例。
重要
尽管通常在通用 Windows 平台 (UWP) 应用中使用 Windows 运行时 C++ 模板库,但此示例使用控制台应用进行演示。 UWP 应用不提供 wprintf_s
等函数。 若要详细了解可在 UWP 应用中使用的类型和函数,请参阅通用 Windows 平台应用中不支持的 CRT 函数和适用于 UWP 应用的 Win32 和 COM。
激活和使用 Windows 运行时组件
包括 (
#include
) 任何所需的 Windows 运行时、Windows 运行时 C++ 模板库或 C++ 标准库标头。#include <Windows.Foundation.h> #include <wrl\wrappers\corewrappers.h> #include <wrl\client.h> #include <stdio.h> using namespace ABI::Windows::Foundation; using namespace Microsoft::WRL; using namespace Microsoft::WRL::Wrappers;
我们建议您在 .cpp 文件中使用
using namespace
指令使代码更具可读性。初始化应用执行所在的线程。 每个应用都必须初始化其线程和线程模型。 此示例使用 Microsoft::WRL::Wrappers::RoInitializeWrapper 类初始化 Windows 运行时,并将 RO_INIT_MULTITHREADED 指定为线程模型。
RoInitializeWrapper
类在构造时调用Windows::Foundation::Initialize
,销毁时调用Windows::Foundation::Uninitialize
。// Initialize the Windows Runtime. RoInitializeWrapper initialize(RO_INIT_MULTITHREADED); if (FAILED(initialize)) { return PrintError(__LINE__, initialize); }
在第二个语句中,RoInitializeWrapper::HRESULT 运算符从
Windows::Foundation::Initialize
调用返回HRESULT
。为
ABI::Windows::Foundation::IUriRuntimeClassFactory
接口创建激活工厂。// Get the activation factory for the IUriRuntimeClass interface. ComPtr<IUriRuntimeClassFactory> uriFactory; HRESULT hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_Foundation_Uri).Get(), &uriFactory); if (FAILED(hr)) { return PrintError(__LINE__, hr); }
Windows 运行时使用完全限定名来标识类型。
RuntimeClass_Windows_Foundation_Uri
参数是 Windows 运行时提供的字符串,其中包含所需的运行时类名称。初始化 Microsoft::WRL::Wrappers::HString 变量,其用于表示 URI
"https://www.microsoft.com"
。// Create a string that represents a URI. HString uriHString; hr = uriHString.Set(L"http://www.microsoft.com"); if (FAILED(hr)) { return PrintError(__LINE__, hr); }
在 Windows 运行时中,不要为 Windows 运行时将使用的字符串分配内存。 相反,Windows 运行时会在它维护和用于操作的缓冲区中创建字符串的副本,然后将句柄返回到其创建的缓冲区。
使用
IUriRuntimeClassFactory::CreateUri
工厂方法创建ABI::Windows::Foundation::IUriRuntimeClass
对象。// Create the IUriRuntimeClass object. ComPtr<IUriRuntimeClass> uri; hr = uriFactory->CreateUri(uriHString.Get(), &uri); if (FAILED(hr)) { return PrintError(__LINE__, hr); }
调用
IUriRuntimeClass::get_Domain
方法以检索Domain
属性的值。// Get the domain part of the URI. HString domainName; hr = uri->get_Domain(domainName.GetAddressOf()); if (FAILED(hr)) { return PrintError(__LINE__, hr); }
将域名输出到控制台并返回。 所有
ComPtr
和 RAII 对象都离开范围并自动释放。// Print the domain name and return. wprintf_s(L"Domain name: %s\n", domainName.GetRawBuffer(nullptr)); // All smart pointers and RAII objects go out of scope here.
WindowsGetStringRawBuffer 函数可检索 URI 字符串的基础 Unicode 格式。
以下是完整示例:
// wrl-consume-component.cpp
// compile with: runtimeobject.lib
#include <Windows.Foundation.h>
#include <wrl\wrappers\corewrappers.h>
#include <wrl\client.h>
#include <stdio.h>
using namespace ABI::Windows::Foundation;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
// Prints an error string for the provided source code line and HRESULT
// value and returns the HRESULT value as an int.
int PrintError(unsigned int line, HRESULT hr)
{
wprintf_s(L"ERROR: Line:%d HRESULT: 0x%X\n", line, hr);
return hr;
}
int wmain()
{
// Initialize the Windows Runtime.
RoInitializeWrapper initialize(RO_INIT_MULTITHREADED);
if (FAILED(initialize))
{
return PrintError(__LINE__, initialize);
}
// Get the activation factory for the IUriRuntimeClass interface.
ComPtr<IUriRuntimeClassFactory> uriFactory;
HRESULT hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_Foundation_Uri).Get(), &uriFactory);
if (FAILED(hr))
{
return PrintError(__LINE__, hr);
}
// Create a string that represents a URI.
HString uriHString;
hr = uriHString.Set(L"http://www.microsoft.com");
if (FAILED(hr))
{
return PrintError(__LINE__, hr);
}
// Create the IUriRuntimeClass object.
ComPtr<IUriRuntimeClass> uri;
hr = uriFactory->CreateUri(uriHString.Get(), &uri);
if (FAILED(hr))
{
return PrintError(__LINE__, hr);
}
// Get the domain part of the URI.
HString domainName;
hr = uri->get_Domain(domainName.GetAddressOf());
if (FAILED(hr))
{
return PrintError(__LINE__, hr);
}
// Print the domain name and return.
wprintf_s(L"Domain name: %s\n", domainName.GetRawBuffer(nullptr));
// All smart pointers and RAII objects go out of scope here.
}
/*
Output:
Domain name: microsoft.com
*/
编译代码
若要编译代码,请复制代码并将其粘贴到 Visual Studio 项目中,或粘贴到一个名为 wrl-consume-component.cpp
的文件中,然后在 Visual Studio 命令提示符窗口中运行以下命令。
cl.exe wrl-consume-component.cpp runtimeobject.lib