Создание компонентов среды выполнения Windows с помощью C++/WinRTWindows Runtime components with C++/WinRT

В этом разделе показано, как использовать C++/WinRT для создания и использования компонента Среда выполнения Windows компонентом — , который можно вызвать из универсального приложения Windows, созданного с помощью любого языка среда выполнения Windows.This topic shows how to use C++/WinRT to create and consume a Windows Runtime component—a component that's callable from a Universal Windows app built using any Windows Runtime language.

Существует несколько причин для создания среда выполнения Windows компонента в C++/Винрт.There are several reasons for building a Windows Runtime component in C++/WinRT.

  • Для эффективного использования преимуществ C++ в сложных или ресурсоемких операциях.To enjoy the performance advantage of C++ in complex or computationally intensive operations.
  • Повторное использование стандартного кода C++, который уже написан и протестирован.To reuse standard C++ code that's already written and tested.
  • Для предоставления функциональных возможностей Win32 для приложения универсальная платформа Windows (UWP), написанного на, например C#.To expose Win32 functionality to a Universal Windows Platform (UWP) app written in, for example, C#.

Как правило, при создании компонента C++/WinRT можно использовать типы из стандартной библиотеки C++ и встроенные типы, за исключением границ интерфейса, в которых данные передаются в код другого пакета и из него .winmd .In general, when you author your C++/WinRT component, you can use types from the standard C++ library, and built-in types, except at the application binary interface (ABI) boundary where you're passing data to and from code in another .winmd package. В ABI используйте типы среда выполнения Windows.At the ABI, use Windows Runtime types. Кроме того, в коде C++/WinRT используйте такие типы, как делегат и Event, для реализации событий, которые могут быть вызваны из компонента и обрабатываться на другом языке.In addition, in your C++/WinRT code, use types such as delegate and event to implement events that can be raised from your component and handled in another language. Дополнительные сведения о C++/Винрт. см. в разделе c++/WinRTSee C++/WinRT for more info about C++/WinRT.

Оставшаяся часть этого раздела посвящена созданию среда выполнения Windows компонента в C++/WinRT и последующему его использованию из приложения.The remainder of this topic walks you through how to author a Windows Runtime component in C++/WinRT, and then how to consume it from an application.

Компонент среда выполнения Windows, который предстоит создать в этом разделе, содержит класс среды выполнения, представляющий термометр.The Windows Runtime component that you'll build in this topic contains a runtime class representing a thermometer. В этом разделе также демонстрируется основное приложение, использующее класс среды выполнения термометра, и вызывается функция для настройки температуры.The topic also demonstrates a Core App that consumes the thermometer runtime class, and calls a function to adjust the temperature.

Примечание

Сведения об установке и использовании расширения C++/WinRT для Visual Studio (VSIX) и пакета NuGet (которые вместе обеспечивают поддержку шаблона проекта и сборки) см. в разделе о поддержке C++/WinRT в Visual Studio.For info about installing and using the C++/WinRT Visual Studio Extension (VSIX) and the NuGet package (which together provide project template and build support), see Visual Studio support for C++/WinRT.

Важно!

Основные понятия и термины, которые помогают понять, как использовать и создавать классы среды выполнения с помощью C++/WinRT, описаны в разделах Использование интерфейсов API с помощью C++/WinRT и Создание интерфейсов API с помощью C++/WinRT.For essential concepts and terms that support your understanding of how to consume and author runtime classes with C++/WinRT, see Consume APIs with C++/WinRT and Author APIs with C++/WinRT.

Создание среда выполнения Windows компонента (Сермометерврк)Create a Windows Runtime component (ThermometerWRC)

Начните с создания проекта в Microsoft Visual Studio.Begin by creating a new project in Microsoft Visual Studio. Создайте проект Среда выполнения Windows компонента (C++/WinRT) и назовите его сермометерврк (для "компонента" термометр среда выполнения Windows Component ").Create a Windows Runtime Component (C++/WinRT) project, and name it ThermometerWRC (for "thermometer Windows Runtime component"). Убедитесь, что снят флажок Поместить решение и проект в одном каталоге.Make sure that Place solution and project in the same directory is unchecked. В качестве цели выберите последнюю общедоступную (то есть не предварительную) версию Windows SDK.Target the latest generally-available (that is, not preview) version of the Windows SDK. Именование проекта сермометерврк предоставит вам самый простой способ работы с остальными шагами, описанными в этом разделе.Naming the project ThermometerWRC will give you the easiest experience with the rest of the steps in this topic.

На этом этапе проект создавать не нужно.Don't build the project yet.

Созданный проект содержит файл с именем Class.idl.The newly-created project contains a file named Class.idl. В обозревателе решений переименуйте файл Thermometer.idl (при переименовании файла с расширением .idl также автоматически переименовываются зависимые файлы .h и .cpp).In Solution Explorer, rename that file Thermometer.idl (renaming the .idl file automatically renames the dependent .h and .cpp files, too). Замените содержимое Thermometer.idl на перечисленное ниже.Replace the contents of Thermometer.idl with the listing below.

// Thermometer.idl
namespace ThermometerWRC
{
    runtimeclass Thermometer
    {
        Thermometer();
        void AdjustTemperature(Single deltaFahrenheit);
    };
}

Сохраните файл.Save the file. В данный момент проект не будет строиться до завершения, но сборка сейчас будет полезной, поскольку создает файлы исходного кода, в которых реализуется класс среды выполнения термометра .The project won't build to completion at the moment, but building now is a useful thing to do because it generates the source code files in which you'll implement the Thermometer runtime class. Так что действуйте и выполняйте сборку сейчас (ошибки сборки, которые можно ожидать на этом этапе, связанны с тем, что не удалось найти Class.h и Class.g.h).So go ahead and build now (the build errors you can expect to see at this stage have to do with Class.h and Class.g.h not being found).

Во время сборки запускается инструмент midl.exe для создания файла метаданных компонента среды выполнения Windows (\ThermometerWRC\Debug\ThermometerWRC\ThermometerWRC.winmd).During the build process, the midl.exe tool is run to create your component's Windows Runtime metadata file (which is \ThermometerWRC\Debug\ThermometerWRC\ThermometerWRC.winmd). Затем запускается средство cppwinrt.exe (с параметром -component) для создания файлов исходного кода для поддержки создания компонента.Then, the cppwinrt.exe tool is run (with the -component option) to generate source code files to support you in authoring your component. Эти файлы включают заглушки, чтобы приступить к реализации класса среды выполнения термометра , объявленного в IDL.These files include stubs to get you started implementing the Thermometer runtime class that you declared in your IDL. Это заглушки \ThermometerWRC\ThermometerWRC\Generated Files\sources\Thermometer.h и Thermometer.cpp.Those stubs are \ThermometerWRC\ThermometerWRC\Generated Files\sources\Thermometer.h and Thermometer.cpp.

Щелкните правой кнопкой мыши узел проекта и нажмите кнопку Открыть папку в проводнике.Right-click the project node and click Open Folder in File Explorer. После этого в проводнике откроется папка проекта.This opens the project folder in File Explorer. Там скопируйте файлы заглушки Thermometer.h и Thermometer.cpp из папки \ThermometerWRC\ThermometerWRC\Generated Files\sources\ в папку, содержащую файлы проекта (\ThermometerWRC\ThermometerWRC\), и замените файлы в месте назначения.There, copy the stub files Thermometer.h and Thermometer.cpp from the folder \ThermometerWRC\ThermometerWRC\Generated Files\sources\ and into the folder that contains your project files, which is \ThermometerWRC\ThermometerWRC\, and replace the files in the destination. Теперь давайте откроем Thermometer.h и Thermometer.cpp и реализуем класс среды выполнения.Now, let's open Thermometer.h and Thermometer.cpp and implement our runtime class. В Thermometer.h добавьте новый закрытый член в реализацию (ане в фабричную реализацию) термометра.In Thermometer.h, add a new private member to the implementation (not the factory implementation) of Thermometer.

// Thermometer.h
...
namespace winrt::ThermometerWRC::implementation
{
    struct Thermometer : ThermometerT<Thermometer>
    {
        ...

    private:
        float m_temperatureFahrenheit { 0.f };
    };
}
...

В Thermometer.cpp реализуйте метод аджусттемпературе , как показано в приведенном ниже списке.In Thermometer.cpp, implement the AdjustTemperature method as shown in the listing below.

// Thermometer.cpp
...
namespace winrt::ThermometerWRC::implementation
{
    void Thermometer::AdjustTemperature(float deltaFahrenheit)
    {
        m_temperatureFahrenheit += deltaFahrenheit;
    }
}

Нужно также удалить static_assert из обоих файлов.You'll also need to delete the static_assert from both files.

Если какие-либо предупреждения не позволяют выполнить сборку, тогда устраните их или установите для свойства проекта C/C++ > Общие > Обрабатывать предупреждения как ошибки значение Нет (/WX-) и выполните сборку проекта заново.If any warnings prevent you from building, then either resolve them or set the project property C/C++ > General > Treat Warnings As Errors to No (/WX-), and build the project again.

Создание основного приложения (Сермометеркореапп) для тестирования компонента среда выполнения WindowsCreate a Core App (ThermometerCoreApp) to test the Windows Runtime component

Теперь создайте новый проект (в решении сермометерврк или в новом).Now create a new project (either in your ThermometerWRC solution, or in a new one). Создайте проект основного приложения (C++/WinRT) и назовите его сермометеркореапп.Create a Core App (C++/WinRT) project, and name it ThermometerCoreApp. Задайте сермометеркореапп в качестве запускаемого проекта, если два проекта находятся в одном решении.Set ThermometerCoreApp as the startup project if the two projects are in the same solution.

Примечание

Как упоминалось ранее, в папке создается файл метаданных среда выполнения Windows для компонента среда выполнения Windows (проект которого называется сермометерврк) \ThermometerWRC\Debug\ThermometerWRC\ .As mentioned earlier, the Windows Runtime metadata file for your Windows Runtime component (whose project you named ThermometerWRC) is created in the folder \ThermometerWRC\Debug\ThermometerWRC\. Первый сегмент этого пути — это имя папки, содержащей файл решения. Следующий сегмент — это подкаталог с именем Debug. Последний сегмент — это подкаталог, названный для компонента среды выполнения Windows.The first segment of that path is the name of the folder that contains your solution file; the next segment is the subdirectory of that named Debug; and the last segment is the subdirectory of that named for your Windows Runtime component. Если вы не назначите имя проекта сермометерврк, файл метаданных будет находиться в папке \<YourProjectName>\Debug\<YourProjectName>\ .If you didn't name your project ThermometerWRC, then your metadata file will be in the folder \<YourProjectName>\Debug\<YourProjectName>\.

Теперь в проекте основного приложения (сермометеркореапп) добавьте ссылку и перейдите к \ThermometerWRC\Debug\ThermometerWRC\ThermometerWRC.winmd (или добавьте ссылку проекта на проект, если два проекта находятся в одном решении).Now, in your Core App project (ThermometerCoreApp), add a reference, and browse to \ThermometerWRC\Debug\ThermometerWRC\ThermometerWRC.winmd (or add a project-to-project reference, if the two projects are in the same solution). Нажмите кнопку Добавить, а затем кнопку OK.Click Add, and then OK. Теперь создайте сермометеркореапп.Now build ThermometerCoreApp. В маловероятном случае, если отображается сообщение об ошибке, что файл полезных данных readme.txt не существует, исключите этот файл из проекта компонента Среда выполнения Windows, перестройте его и перестройте сермометеркореапп.In the unlikely event that you see an error that the payload file readme.txt doesn't exist, exclude that file from the Windows Runtime component project, rebuild it, then rebuild ThermometerCoreApp.

Во время сборки запускается средство cppwinrt.exe для обработки указанного файла .winmd в файлы исходного кода, содержащие проецируемые типы для поддержки использования вашего компонента.During the build process, the cppwinrt.exe tool is run to process the referenced .winmd file into source code files containing projected types to support you in consuming your component. Заголовок проецируемых типов для классов среды выполнения вашего компонента — с именем ThermometerWRC.h— создается в папке \ThermometerCoreApp\ThermometerCoreApp\Generated Files\winrt\.The header for the projected types for your component's runtime classes—named ThermometerWRC.h—is generated into the folder \ThermometerCoreApp\ThermometerCoreApp\Generated Files\winrt\.

Включите этот заголовок в App.cpp.Include that header in App.cpp.

// App.cpp
...
#include <winrt/ThermometerWRC.h>
...

Кроме того App.cpp , в добавьте следующий код для создания экземпляра объекта термометра (с помощью конструктора по умолчанию проецируемого типа) и вызовите метод для объекта термометра.Also in App.cpp, add the following code to instantiate a Thermometer object (using the projected type's default constructor), and call a method on the thermometer object.

struct App : implements<App, IFrameworkViewSource, IFrameworkView>
{
    ThermometerWRC::Thermometer m_thermometer;
    ...
    
    void OnPointerPressed(IInspectable const &, PointerEventArgs const & args)
    {
        m_thermometer.AdjustTemperature(1.f);
        ...
    }
    ...
};

Каждый раз при щелчке по окну увеличивается температура объекта термометра.Each time you click the window, you increment the thermometer object's temperature. Вы можете задать точки останова, если хотите пошагово выполнить код, чтобы убедиться, что приложение действительно вызывает компонент среда выполнения Windows.You can set breakpoints if you want to step through the code to confirm that the application really is calling into the Windows Runtime component.

Дальнейшие действияNext steps

Чтобы добавить еще больше функциональных возможностей или новых типов среда выполнения Windows в компонент C++/WinRT среда выполнения Windows, можно следовать тем же шаблонам, которые показаны выше.To add even more functionality, or new Windows Runtime types, to your C++/WinRT Windows Runtime component, you can follow the same patterns shown above. Во-первых, используйте IDL для определения функциональности, которую нужно предоставить.First, use IDL to define the functionality you want to expose. Затем выполните сборку проекта в Visual Studio, чтобы создать реализацию заглушки.Then build the project in Visual Studio to generate a stub implementation. А затем завершите реализацию соответствующим образом.And then complete the implementation as appropriate. Все методы, свойства и события, определенные в IDL, видимы для приложения, использующего компонент среда выполнения Windows.Any methods, properties, and events that you define in IDL are visible to the application that consumes your Windows Runtime Component. Дополнительные сведения о IDL см. в статье Введение в язык MIDL 3,0.For more info about IDL, see Introduction to Microsoft Interface Definition Language 3.0.

Пример добавления события в компонент среда выполнения Windows см. в разделе Создание событий в C++/WinRT.For an example of how to add an event to your Windows Runtime Component, see Author events in C++/WinRT.

Устранение неполадокTroubleshooting

СимптомSymptom СредствоRemedy
В приложении C++/WinRT при работе с компонентом среды выполнения Windows для C#, который использует XAML, компилятор выдает ошибку такого вида: "MyNamespace_XamlTypeInfo" не является членом "winrt::MyNamespace" . Здесь MyNamespace — это имя пространства имен компонента среды выполнения Windows.In a C++/WinRT app, when consuming a C# Windows Runtime component that uses XAML, the compiler produces an error of the form "'MyNamespace_XamlTypeInfo': is not a member of 'winrt::MyNamespace'"—where MyNamespace is the name of the Windows Runtime component's namespace. В файле pch.h используемого приложения C++/WinRT добавьте #include <winrt/MyNamespace.MyNamespace_XamlTypeInfo.h>, заменив MyNamespace соответствующим образом.In pch.h in the consuming C++/WinRT app, add #include <winrt/MyNamespace.MyNamespace_XamlTypeInfo.h>—replacing MyNamespace as appropriate.