方法: WRL を使用して Windows ランタイム コンポーネントをアクティブ化し使用する
このドキュメントでは、Windows ランタイム C++ テンプレート ライブラリ (WRL) を使って Windows ランタイムを初期化する方法と、Windows ランタイム コンポーネントをアクティブ化して使う方法について説明します。
コンポーネントを使用するには、コンポーネントによって実装されている型へのインターフェイス ポインターを取得する必要があります。 また、Windows ランタイムの基になるテクノロジはコンポーネント オブジェクト モデル (COM) であるため、COM の規則に従って型のインスタンスを保持する必要があります。 たとえば、型がメモリから削除されるタイミングを決定する "参照カウント" を保持する必要があります。
Windows ランタイムの使用を簡略化するために、Windows ランタイム C++ テンプレート ライブラリには、自動的に参照カウントを実行するスマート ポインター テンプレートである ComPtr<T> が用意されています。 変数を宣言するときは、 ComPtr<
interface-name>
identifier を指定します。 インターフェイスのメンバーにアクセスするには、識別子に矢印のメンバー アクセス演算子 (->
) を適用します。
重要
インターフェイス関数を呼び出す際は、HRESULT の戻り値を必ずテストしてください。
Windows ランタイム コンポーネントのアクティブ化と使用
次の手順では、Windows::Foundation::IUriRuntimeClass
インターフェイスを使用して Windows ランタイム コンポーネントのアクティブ化ファクトリを作成する方法、そのコンポーネントのインスタンスを作成する方法、プロパティ値を取得する方法を示します。 また、Windows ランタイムを初期化する方法も示します。 完全な例を次に示します。
重要
通常は、ユニバーサル Windows プラットフォーム (UWP) アプリで Windows ランタイム C++ テンプレート ライブラリを使用しますが、この例ではコンソール アプリを使用して説明します。 wprintf_s
のような関数は、UWP アプリから使用することはできません。 UWP アプリケーション内で使用できる関数と型の詳細については、「ユニバーサル Windows プラットフォームでサポートされていない CRT 関数」と「UWP アプリケーション用の Win32 と COM」を参照してください。
Windows ランタイム コンポーネントをアクティブ化して使用するには
必須の Windows ランタイム、Windows ランタイム C++ テンプレートライブラリ、または C++ 標準ライブラリのヘッダーをインクルード (
#include
) します。#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); }
2 番目のステートメントでは、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 ランタイムによって提供される文字列であり、必須のランタイム クラス名が含まれています。URI
"https://www.microsoft.com"
を表す Microsoft::WRL::Wrappers::HString 変数を初期化します。// 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