Практическое руководство. Активация и использование компонента среды выполнения Windows с помощью WRL

В этом документе показано, как использовать библиотеку шаблонов C++ среда выполнения Windows C++ для инициализации среда выполнения Windows и активации и использования компонента среда выполнения Windows.

Для использования компонента необходимо получить указатель интерфейса на тип, который реализуется компонентом. И поскольку базовая технология среда выполнения Windows является объектной моделью компонента (COM), необходимо следовать правилам COM для поддержания экземпляра типа. Например, необходимо сохранить счетчик ссылок, определяющий, когда тип удаляется из памяти.

Чтобы упростить использование среда выполнения Windows, библиотека шаблонов C++ среда выполнения Windows C++ предоставляет шаблон интеллектуального указателя ComPtr<T>, который автоматически выполняет подсчет ссылок. При объявлении переменной укажите ComPtr<идентификатор имени>интерфейса. Для обращения к членам интерфейса примените оператор доступа к членам класса в виде стрелки (->) к идентификатору.

Важно!

При вызове функции интерфейса всегда проверяйте возвращаемое значение HRESULT.

Активация и использование компонента среды выполнения Windows

Следующие шаги используют Windows::Foundation::IUriRuntimeClass интерфейс для демонстрации создания фабрики активации для компонента среда выполнения Windows, создания экземпляра этого компонента и получения значения свойства. Они также показывают, как инициализировать среда выполнения Windows. Ниже приведен полный пример.

Важно!

Хотя обычно используется библиотека шаблонов C++ среда выполнения Windows в приложении универсальная платформа Windows (UWP), в этом примере используется консольное приложение для иллюстрации. Такие функции, как wprintf_s недоступны в приложении UWP. Дополнительные сведения о типах и функциях, которые можно использовать в приложении UWP, см. в функциях CRT, которые не поддерживаются в приложениях универсальная платформа Windows и Win32 и COM для приложений UWP.

Активация и использование компонента среды выполнения Windows

  1. Включите (#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;
    

    Рекомендуется использовать директиву using namespace в CPP-файле, чтобы сделать код более удобочитаемым.

  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);
    }
    

    Во втором операторе оператор RoInitializeWrapper::HRESULT возвращает HRESULTWindows::Foundation::Initializeвызов.

  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. Инициализация переменной 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 создает копию строки в буфере, который он поддерживает и использует для операций, а затем возвращает дескриптор созданному буферу.

  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.

Ниже приведен полный пример.

// 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

См. также

Библиотека шаблонов C++ для среды выполнения Windows (WRL)