方法: 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 ランタイム コンポーネントをアクティブ化して使用するには

  1. 必須の 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 ディレクティブを使用することをお勧めします。

  2. アプリが実行されるスレッドを初期化します。 すべてのアプリケーションでスレッドとスレッド モデルを初期化する必要があります。 この例では、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::InitializeHRESULT が返されます。

  3. 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 ランタイムによって提供される文字列であり、必須のランタイム クラス名が含まれています。

  4. 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 ランタイムによって、操作用に保持および使用される文字列のコピーがバッファーに作成され、作成されたバッファーへのハンドルが返されます。

  5. 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);
    }
    
  6. 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);
    }
    
  7. ドメイン名をコンソールに出力して返ります。 すべての 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

関連項目

Windows ランタイム C++ テンプレート ライブラリ (WRL)