Введение в C++/WinRT

 

 

C++/WinRT — это полностью стандартная проекция языка C++17 для API среды выполнения Windows (WinRT), реализованная как библиотека на основе файлов заголовков и предназначенная для предоставления вам первоклассного доступа к современным интерфейсам API Windows. С помощью C++/WinRT можно создавать и использовать интерфейсы API среды выполнения Windows, используя любой совместимый со стандартами компилятор C++17. В пакет Windows SDK входит среда C++/WinRT, которая впервые появилась в версии 10.0.17134.0 (Windows 10, версия 1803).

C++/WinRT — это рекомендуемая корпорацией Майкрософт замена для проекции языка C++/CX и библиотеки шаблонов C++ для среды выполнения Windows (WRL). Полный список статей о C++/WinRT содержит информацию о взаимодействии с C++/CX и WRL и о переносе из них.

Важно!

Некоторые наиболее важные аспекты C++/WinRT, которые следует учитывать, описаны в разделах Поддержка пакетов SDK для C++/WinRT и Поддержка Visual Studio для C++/WinRT, XAML, расширения VSIX и пакета NuGet.

См. раздел Где можно найти примеры приложений C++/WinRT?

Языковые проекции

Среда выполнения Windows основывается на API Component Object Model (COM) и предусматривает доступ к ней через языковые проекции. Использование проекции позволяет скрывать подробности COM и обеспечить более естественный подход к программированию на используемом языке.

Языковая проекция C++/WinRT в содержимом справочных материалов по API среды выполнения Windows

При просмотре API среды выполнения Windows щелкните вверху справа поле со списком Язык и выберите пункт C++/WinRT, чтобы просмотреть синтаксические блоки API в том виде, в котором они отражаются в языковой проекции C++/WinRT.

Поддержка Visual Studio для C++/WinRT, XAML, расширения VSIX и пакета NuGet

Для поддержки Visual Studio вам потребуется Visual Studio 2022 или Visual Studio 2019 или Visual Studio 2017 (по крайней мере версия 15.6; рекомендуется по крайней мере 15.7). С помощью Visual Studio Installer установите рабочую нагрузку Разработка приложений для универсальной платформы Windows. В разделе "Сведения о> установке универсальная платформа Windows разработке проверка универсальная платформа Windows средства C++ (версии 14x), если вы еще этого не сделали. И в Windows Параметры> Privacy и безопасности (Windows 10: Update &Security)> Для разработчиков включите параметр режима разработчика (Windows 10: не загрузка неопубликованных приложений).

Хотя мы рекомендуем выполнять разработку с последними версиями Visual Studio и Windows SDK, если вы используете версию C++/WinRT, которая поставляется вместе с версией Windows SDK, предшествующей версии 10.0.17763.0 (Windows 10 версии 1809), для упомянутых выше заголовков пространств имен Windows в проекте вам потребуется минимальная целевая версия Windows SDK 10.0.17134.0 (Windows 10 версии 1803).

Visual Studio 2022 поставляется со встроенными шаблонами проектов и элементов C++/WinRT, чтобы вы могли сразу же приступить к разработке приложений C++/WinRT. Также предоставляется визуализация встроенной отладки Visual Studio (natvis) проецируемых типов C++/ WinRT, что обеспечивает возможности, аналогичные отладке C#. Natvis автоматически используется для сборок отладки. Дополнительные сведения см. в статье Нативная визуализация отладки Visual Studio для C++/WinRT.

При использовании более старых версий Visual Studio вам нужно будет скачать и установить последнюю версию расширения C++/WinRT для Visual Studio (VSIX) в Visual Studio Marketplace.

  • Расширение VSIX предоставляет шаблоны проектов и элементов C++/WinRT в Visual Studio.
  • Также предоставляется собственная визуализация отладки (natvis) Visual Studio для проецируемых типов C++/WinRT.

Шаблоны проектов Visual Studio для C++/WinRT описаны в следующих разделах. Когда вы создаете проект C++/WinRT с установленной последней версией расширения VSIX, новый проект C++/WinRT автоматически устанавливает пакет NuGet Microsoft.Windows.CppWinRT. Пакет NuGet Microsoft.Windows.CppWinRT обеспечивает поддержку сборки с C++/WinRT (свойства и цели MSBuild), делая проект переносимым между компьютером для разработки и агентом сборки (на котором установлен только пакет NuGet, а не расширение VSIX).

Кроме того, вы можете преобразовать существующий проект, вручную установив пакет NuGet Microsoft.Windows.CppWinRT. После установки (или обновления до) последней версии расширения VSIX откройте существующий проект в Visual Studio и щелкните Проект>Управление пакетами NuGet...>Обзор, введите или вставьте Microsoft.Windows.CppWinRT в поле поиска, выберите элемент в результатах поиска, а затем нажмите кнопку Установить, чтобы установить пакет для этого проекта. После добавления этого пакета вы получите поддержку MSBuild C++/WinRT для проекта, включая вызов инструмента cppwinrt.exe.

Важно!

Если у вас есть проекты, которые были созданы (или обновлены для работы) с версией расширения VSIX ниже, чем 1.0.190128.4, ознакомьтесь с разделом Более ранние версии расширения VSIX. Этот раздел содержит важную информацию о конфигурации проектов, о которой вам необходимо знать, чтобы обновить их для использования последней версии расширения VSIX.

  • Так как C++/WinRT использует компоненты стандарта C++17, пакет NuGet устанавливает для свойства проекта C/C++>Язык>Стандарт языка C++>Стандарт ISO C++17 (/std:c++17) в Visual Studio.
  • Он также добавляет параметр компилятора /bigobj.
  • Кроме того, с помощью пакета добавляется параметр компилятора /await, чтобы включить co_await,
  • и компилятору XAML дается инструкция выдавать Codegen C++/WinRT.
  • Кроме того, может потребоваться задать режим соответствия: Да (/permissive-), что также ограничивает код соответствием стандартам.
  • Еще одно свойство, о котором следует знать, — это C/C++>Общие>Обрабатывать предупреждения как ошибки. Задайте для него значение Да (/WX) или Нет (/WX-) по вашему желанию. Иногда исходные файлы, созданные инструментом cppwinrt.exe, выдают предупреждения до тех пор, пока вы не добавите в них свою реализацию.

Если ваша система настроена, как описано выше, вы сможете создавать или открывать проект C++/WinRT в Visual Studio и развертывать его.

Начиная с версии 2.0, в состав пакета NuGet Microsoft.Windows.CppWinRT входит инструмент cppwinrt.exe. Вы можете указывать на инструмент cppwinrt.exe в файле метаданных среды выполнения Windows (.winmd) для создания стандартной библиотеки C++ на основе файлов заголовков, которая проецирует API, описанные в метаданных, для использования в коде C++/WinRT. Файлы метаданных среды выполнения Windows (.winmd) предоставляют канонический способ описания поверхности API среды выполнения Windows. Если cppwinrt.exe указывает на метаданные, вы можете создать библиотеку для использования с любым классом среды выполнения, реализованным в стороннем компоненте среды выполнения Windows или в вашем приложении. Дополнительные сведения см. в статье Использование API-интерфейсов с помощью C++/WinRT.

С помощью C++/WinRT также можно реализовать собственные классы среды выполнения, используя стандартный язык C++, не прибегая к программированию в стиле COM. Для класса среды выполнения необходимо просто описать типы в IDL-файле, после чего средства midl.exe и cppwinrt.exe автоматически создадут файлы стандартного исходного кода. Можно также реализовать только интерфейсы на основе базового класса C++/WinRT. Дополнительные сведения см. в статье Создание API-интерфейсов в C++/WinRT.

Список параметров настройки для средства cppwinrt.exe, заданных в разделе свойств проекта, см. в файле сведений пакета NuGet Microsoft.Windows.CppWinRT.

Вы можете определить проект, который использует поддержку MSBuild C++/WinRT, по наличию пакета NuGet Microsoft.Windows.CppWinRT, установленного в проекте.

Далее приведены шаблоны проектов Visual Studio, предоставляемые расширением VSIX.

Пустое приложение (C++/WinRT)

Шаблон проекта для приложения универсальной платформы Windows (UWP), которое имеет пользовательский интерфейс XAML.

Visual Studio предоставляет поддержку компилятора XAML для создания заглушек реализаций и заголовков из IDL-файла (.idl), прилагаемого к каждому файлу разметки XAML. В IDL-файле определите все классы локальной среды выполнения, на которые нужно сослаться на XAML-страницах вашего приложения, а затем один раз выполните сборку проекта для создания шаблонов реализации в Generated Files и определений типа заглушки в Generated Files\sources. Затем используйте определения типа заглушки для справки при реализации классов локальной среды выполнения. Также см. раздел о разделении классов среды выполнения на файлы Midl (.idl).

Поддержка области конструирования XAML в Visual Studio для C++/WinRT соответствует таковой для C#. В Visual Studio вы можете использовать вкладку События окна Свойства, чтобы добавить обработчики событий в проект C++/WinRT. Вы также можете вручную добавить обработчики событий в код. Дополнительные сведения см. в статье Обработка событий с помощью делегатов в C++/WinRT.

Приложение основных компонентов (C++/WinRT)

Шаблон проекта для приложения универсальной платформы Windows (UWP), которое не использует XAML.

Вместо этого оно использует заголовок пространства имен C++/WinRT (Windows) для пространства имен Windows.ApplicationModel.Core. После выполнения сборки и запуска щелкните пустое пространство для добавления цветного квадрата, а затем щелкните цветной квадрат, чтобы перетащить его.

Консольное приложение для Windows (C++/WinRT)

Шаблон проекта для клиентского приложения C++/WinRT для Windows Desktop с пользовательским интерфейсом консоли.

Классическое приложение для Windows (C++/WinRT)

Шаблон проекта для клиентского приложения C++/WinRT для Windows Desktop, который отображает Windows.Foundation.Uri среды выполнения Windows внутри MessageBox Win32.

Компонент среды выполнения Windows (C++/WinRT)

Шаблон проекта для компонента, как правило, для использования из универсальной платформы Windows (UWP).

Этот шаблон демонстрирует цепочку инструментов midl.exe>cppwinrt.exe, где метаданные среды выполнения Windows (.winmd) создаются из IDL, а затем из метаданных среды выполнения Windows создаются заглушки реализаций и заголовков.

В IDL-файле определите классы среды выполнения в вашем компоненте, их интерфейс по умолчанию и другие интерфейсы, которые они реализуют. Единожды выполните сборку проекта для создания шаблонов реализаций module.g.cpp и module.h.cpp в Generated Files и определений типа заглушек в Generated Files\sources. Затем используйте определения типов заглушек для справки при реализации классов среды выполнения в вашем компоненте. Также см. раздел о разделении классов среды выполнения на файлы Midl (.idl).

Объедините в пакет созданный двоичный файл компонента среды выполнения Windows и его файл с расширением .winmd с приложением UWP, которое их использует.

Более ранние версии расширения VSIX

Мы рекомендуем установить (или обновить до) последнюю версию расширения VSIX. По умолчанию для него настроено самостоятельное обновление. Если вы это сделаете при наличии проектов, созданных с версией расширения VSIX ранее 1.0.190128.4, следует ознакомиться с этим разделом, содержащим важную информацию об обновлении этих проектов для работы с новой версией. Если вы не выполните обновление, вам все равно будет полезно ознакомиться со сведениями в этом разделе.

С точки зрения поддерживаемых пакетов Windows SDK и версий Visual Studio, а также конфигурации Visual Studio информация в приведенном выше разделе Поддержка Visual Studio для C++/WinRT, XAML, расширения VSIX и пакета NuGet относится к более ранним версиям расширения VSIX. Ниже описываются важные различия в поведении и конфигурации проектов, созданных (или обновленных для работы) с более ранними версиями.

Созданные с версией ранее 1.0.181002.2

Если ваш проект был создан с более ранней версией расширения VSIX, чем 1.0.181002.2, в эту версию расширения VSIX была встроена поддержка сборки C++/WinRT. Проект содержит набор свойств <CppWinRTEnabled>true</CppWinRTEnabled> в файле .vcxproj.

<Project ...>
    <PropertyGroup Label="Globals">
        <CppWinRTEnabled>true</CppWinRTEnabled>
...

Вы можете обновить проект, вручную установив пакет NuGet Microsoft.Windows.CppWinRT. После установки (или обновления до) последней версии расширения VSIX откройте свой проект в Visual Studio и щелкните Проект>Управление пакетами NuGet...>Обзор, введите или вставьте Microsoft.Windows.CppWinRT в поле поиска, выберите элемент в результатах поиска, а затем нажмите кнопку Установить, чтобы установить пакет для вашего проекта.

Созданные с версиями (или обновленные до) 1.0.181002.2–1.0.190128.3

Если проект был создан с версией расширения VSIX между 1.0.181002.2 и 1.0.190128.3 включительно, пакет NuGet Microsoft.Windows.CppWinRT был автоматически установлен в проект по шаблону проекта. Кроме того, может также потребоваться обновить более старый проект для использования версии расширения VSIX в этом диапазоне. Если вы это сделали, так как поддержка сборки все еще присутствовала в версиях расширения VSIX в этом диапазоне, в обновленном проекте может быть установлен или не установлен пакет NuGet Microsoft.Windows.CppWinRT.

Чтобы обновить проект, следуйте инструкциям в предыдущем разделе и убедитесь, что в проекте установлен пакет NuGet Microsoft.Windows.CppWinRT.

Недопустимые конфигурации обновления

В последней версии расширения VSIX для проекта недопустимо иметь свойство <CppWinRTEnabled>true</CppWinRTEnabled>, если на нем также не установлен пакет NuGet Microsoft.Windows.CppWinRT. Проект с такой конфигурацией выдает сообщение об ошибке сборки: "The C++/WinRT VSIX no longer provides project build support. Please add a project reference to the Microsoft.Windows.CppWinRT Nuget package." (C++/WinRT VSIX больше не поддерживает сборку проекта. Добавьте ссылку на пакет Nuget Microsoft.Windows.CppWinRT в проекте).

Как упоминалось выше, проект C++/WinRT теперь должен иметь установленный пакет NuGet.

Так как элемент <CppWinRTEnabled> устарел, вы можете при необходимости отредактировать параметр .vcxproj и удалить элемент. Это не обязательно, но возможно.

Кроме того, если параметр .vcxproj содержит <RequiredBundles>$(RequiredBundles);Microsoft.Windows.CppWinRT</RequiredBundles>, вы можете удалить его, чтобы можно было выполнить сборку, не устанавливая расширение VSIX C++/WinRT.

Поддержка пакетов SDK для C++/WinRT

Хотя теперь она присутствует только в целях обеспечения совместимости, начиная с версии 10.0.17134.0 (Windows 10, версия 1803), Windows SDK содержит стандартную библиотеку C++ на основе файлов заголовков для использования основных API-интерфейсов Windows (API среды выполнения Windows и пространства имен Windows). Эти заголовки размещены в папке %WindowsSdkDir%Include<WindowsTargetPlatformVersion>\cppwinrt\winrt. Начиная с версии Windows SDK 10.0.17763.0 (Windows 10, версия 1809), эти заголовки создаются в папке $(GeneratedFilesDir) проекта.

Опять-таки, в целях обеспечения совместимости пакет Windows SDK также поставляется с инструментом cppwinrt.exe. Однако мы рекомендуем вместо этого установить и использовать самую последнюю версию cppwinrt.exe, которая включена в пакет NuGet Microsoft.Windows.CppWinRT. Этот пакет и cppwinrt.exe описаны в разделах выше.

Пользовательские типы в проекции C++/WinRT

При использовании C++/WinRT можно применять стандартные функции языка C++ и стандартные типы данных C++ и C++/WinRT, включая некоторые типы данных стандартной библиотеки C++. Однако вы также получите сведения о некоторых пользовательских типах данных в проекции и сможете использовать их. Например, мы используем winrt::hstring в кратком примере кода в разделе Начало работы с C++/WinRT.

winrt::com_array является еще одним типом, который вы, скорее всего, используете в определенный момент. При этом вы с меньшей вероятностью будете использовать напрямую такие типы, как winrt::array_view. Вы можете решить не использовать его, чтобы у вас не было кода, требующего изменений, если эквивалентный тип появится в стандартной библиотеке C++.

Предупреждение

Кроме того, существуют типы, которые можно обнаружить, если внимательно изучить заголовки пространства имен Windows C++/WinRT. Примером служит winrt::param::hstring, но существуют и примеры для коллекции. Они существуют исключительно для оптимизации привязки входных параметров, при этом помогают существенно повысить производительность и обеспечивают поддержку большинства шаблонов вызовов для связанных стандартных типов и контейнеров C++. Эти типы будут использоваться проекцией тогда, когда они будут наиболее эффективны. Они существенно оптимизированы и не предназначены для общего использования. Не применяйте их самостоятельно. Вам также не следует использовать что-либо из пространства имен winrt::impl, так как это типы реализации, которые могут быть изменены. Вам следует продолжать использовать стандартные типы или типы из пространства имен winrt.

Также см. статью о передаче параметров в интерфейс ABI.

Важные API