Вызовы функций WinRT из низкоуровневого C++.

Данная публикация является переводом статьи Kristoffer Henriksson “Calling WinRT functions from low level C++”.

Проецирование верхнего уровня для WinRT, доступное в C++, делает работу с WinRT на C++ куда проще. Оно управляет отчётами об ошибках, подсчетом ссылок, конвертированием строк и т.п. Для примера давайте рассмотрим следующий высокоуровневый код на C++ для получения пути к папке TEMP:

  void GetTempFolderPathHighLevel(std::wstring& path)
  {
    path = Windows::Storage::ApplicationData::Current->TemporaryFolder->Path->Data();
  }

Коротко, просто и точно в цель. Низкоуровневый эквивалент выглядит ужасно:

  #include <windows.storage.h>
  #include <wrl/client.h>
  #include <wrl/wrappers/corewrappers.h>
  
  HRESULT GetTempFolderPath(std::wstring& path)
  {
    HRESULT hr;
    Microsoft::WRL::ComPtr<ABI::Windows::Storage::IApplicationDataStatics> applicationDataStatics;
   
    hr = Windows::Foundation::GetActivationFactory(Microsoft::WRL::Wrappers::HStringReference(RuntimeClass_Windows_Storage_ApplicationData).Get(), &applicationDataStatics);
    if (FAILED(hr))
    {
      return hr;
    }
   
    Microsoft::WRL::ComPtr<ABI::Windows::Storage::IApplicationData> applicationData;
    hr = applicationDataStatics->get_Current(&applicationData);
    if (FAILED(hr))
    {
      return hr;
    }
   
    Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageFolder> storageFolder;
    hr = applicationData->get_TemporaryFolder(&storageFolder);
    if (FAILED(hr))
    {
      return hr;
    }
   
    Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageItem> storageItem;
    hr = storageFolder.As(&storageItem);
    if (FAILED(hr))
    {
      return hr;
    }
   
    HSTRING folderName;
    hr = storageItem->get_Path(&folderName);
    if (FAILED(hr))
    {
      return hr;
    }
   
    UINT32 length;
    PCWSTR value = WindowsGetStringRawBuffer(folderName, &length);
    path = value;
    return S_OK;
  }