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

В этом разделе показано, как использовать C++/WinRT для создания и использования компонента среда выполнения Windows , который можно вызывать из универсального приложения для Windows, созданного на любом среда выполнения Windows языке.

Существует несколько причин для создания компонента среда выполнения Windows в C++/WinRT.

  • Использование преимущества производительности C++ в сложных или ресурсоемких операциях.
  • Повторное использование стандартного кода C++, который уже написан и протестирован.
  • Предоставление функциональных возможностей Win32 приложению универсальная платформа Windows (UWP), написанному на языке, например C#.

Как правило, при создании компонента C++/WinRT можно использовать типы из стандартной библиотеки C++ и встроенные типы, за исключением границы двоичного интерфейса приложения (ABI), где данные передаются в код в другом пакете и из него .winmd . В ABI используйте среда выполнения Windows типы. Кроме того, в коде C++/WinRT используйте такие типы, как делегат и событие, для реализации событий, которые могут быть вызваны из компонента и обработаны на другом языке. Дополнительные сведения о C++/WinRT см. в разделе C++/WinRT .

В оставшейся части этого раздела описывается, как создать компонент среда выполнения Windows в C++/WinRT, а затем использовать его из приложения.

Компонент среда выполнения Windows, который вы создадите в этом разделе, содержит класс среды выполнения, представляющий термометр. В этом разделе также демонстрируется основное приложение, которое использует класс среды выполнения термометра и вызывает функцию для настройки температуры.

Примечание

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

Важно!

Основные понятия и термины, которые помогают понять, как использовать и создавать классы среды выполнения с помощью C++/WinRT, описаны в разделах Использование интерфейсов API с помощью C++/WinRT и Создание интерфейсов API с помощью C++/WinRT.

Рекомендации по именованию для библиотек DLL среда выполнения Windows компонентов

Важно!

В этом разделе описывается соглашение об именовании, которое рекомендуется использовать для .dll файла (DLL), в который создается компонент среда выполнения Windows. Все дело в последовательности активации, которую следует C++/WinRT при использовании класса среды выполнения из компонента среда выполнения Windows.

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

Например, если активируемый класс имеет полное имя Contoso.Instruments.ThermometerWRC.Thermometer, а RoGetActivationFactory завершается сбоем Contoso.Instruments.ThermometerWRC.dll, сначала мы ищем . Если это не найдено, мы будем искать Contoso.Instruments.dll, а затем для Contoso.dll.

При обнаружении библиотеки DLL (в этой последовательности) мы будем использовать точку входа DllGetActivationFactory этой библиотеки DLL, чтобы попытаться получить фабрику напрямую (а не косвенно через функцию RoGetActivationFactory , которую мы впервые попытались). Несмотря на это, конечный результат неотличим для вызывающей стороны и библиотеки DLL.

Этот процесс выполняется полностью автоматически— регистрация или использование инструментов не требуется. Если вы создаете компонент среда выполнения Windows, вам просто нужно использовать соглашение об именовании для библиотек DLL, которое работает с описанным процессом. Если вы используете компонент среда выполнения Windows и он не имеет правильного имени, вы можете переименовать его, как описано.

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

Начните с создания нового проекта в Microsoft Visual Studio. Создайте проект компонента среда выполнения Windows (C++/WinRT) и назовите его ThermometerWRC (для компонента термометра среда выполнения Windows). Убедитесь, что снят флажок Поместить решение и проект в одном каталоге. В качестве цели выберите последнюю общедоступную (то есть не предварительную) версию Windows SDK. Присвоение проекту имени ThermometerWRC даст вам самый простой опыт работы с остальными шагами, описанными в этом разделе.

На этом этапе проект создавать не нужно.

Созданный проект содержит файл с именем Class.idl. В обозревателе решений переименуйте файл Thermometer.idl (при переименовании файла с расширением .idl также автоматически переименовываются зависимые файлы .h и .cpp). Замените содержимое Thermometer.idl на перечисленное ниже.

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

Сохраните файл. На данный момент сборка проекта не будет завершена, но сборка сейчас является полезной вещью, так как он создает файлы исходного кода, в которых вы будете реализовывать класс среды выполнения Thermometer . Так что действуйте и выполняйте сборку сейчас (ошибки сборки, которые можно ожидать на этом этапе, связанны с тем, что не удалось найти Class.h и Class.g.h).

Во время сборки запускается инструмент midl.exe для создания файла метаданных компонента среды выполнения Windows (\ThermometerWRC\Debug\ThermometerWRC\ThermometerWRC.winmd). Затем запускается средство cppwinrt.exe (с параметром -component) для создания файлов исходного кода для поддержки создания компонента. Эти файлы включают заглушки, позволяющие приступить к реализации класса среды выполнения Thermometer , объявленного в IDL. Это заглушки \ThermometerWRC\ThermometerWRC\Generated Files\sources\Thermometer.h и Thermometer.cpp.

Щелкните правой кнопкой мыши узел проекта и нажмите кнопку Открыть папку в проводнике. После этого в проводнике откроется папка проекта. Там скопируйте файлы заглушки Thermometer.h и Thermometer.cpp из папки \ThermometerWRC\ThermometerWRC\Generated Files\sources\ в папку, содержащую файлы проекта (\ThermometerWRC\ThermometerWRC\), и замените файлы в месте назначения. Теперь давайте откроем Thermometer.h и Thermometer.cpp и реализуем класс среды выполнения. В Thermometer.hдобавьте новый частный член в реализацию (а не в реализацию фабрики) Thermometer.

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

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

В Thermometer.cppреализуйте метод AdjustTemperature , как показано в приведенном ниже списке.

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

В верхней части Thermometer.h и Thermometer.cpp вы увидите static_assert, который нужно удалить. Теперь сборка проекта будет выполнена.

Если какие-либо предупреждения не позволяют выполнить сборку, тогда устраните их или установите для свойства проекта C/C++>Общие>Обрабатывать предупреждения как ошибки значение Нет (/WX-) и выполните сборку проекта заново.

Создание основного приложения (ThermometerCoreApp) для тестирования компонента среда выполнения Windows

Теперь создайте новый проект (в решении ThermometerWRC или в новом). Создайте проект основного приложения (C++/WinRT) и назовите его ThermometerCoreApp. Задайте ThermometerCoreApp в качестве запускаемого проекта, если два проекта находятся в одном решении.

Примечание

Как упоминалось ранее, файл метаданных среда выполнения Windows для компонента среда выполнения Windows (проект которого вы назвали ThermometerWRC) создается в папке \ThermometerWRC\Debug\ThermometerWRC\. Первый сегмент этого пути — это имя папки, содержащей файл решения. Следующий сегмент — это подкаталог с именем Debug. Последний сегмент — это подкаталог, названный для компонента среды выполнения Windows. Если вы не назвали проект ThermometerWRC, файл метаданных будет находиться в папке \<YourProjectName>\Debug\<YourProjectName>\.

Теперь в проекте основного приложения (ThermometerCoreApp) добавьте ссылку и перейдите по \ThermometerWRC\Debug\ThermometerWRC\ThermometerWRC.winmd ссылке (или добавьте ссылку между проектами, если два проекта находятся в одном решении). Нажмите кнопку Добавить, а затем кнопку OK. Теперь выполните сборку ThermometerCoreApp. В маловероятном случае, если вы увидите ошибку, что файл readme.txt полезных данных не существует, исключите этот файл из проекта компонента среда выполнения Windows, перестройте его, а затем перестройте ThermometerCoreApp.

Во время сборки запускается средство cppwinrt.exe для обработки указанного файла .winmd в файлы исходного кода, содержащие проецируемые типы для поддержки использования вашего компонента. Заголовок проецируемых типов для классов среды выполнения компонента с именем ThermometerWRC.hсоздается в папке \ThermometerCoreApp\ThermometerCoreApp\Generated Files\winrt\.

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

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

Кроме того, в App.cppдобавьте следующий код, чтобы создать экземпляр объекта Thermometer (с помощью конструктора по умолчанию проецируемого типа) и вызвать метод для объекта термометра.

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

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

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

Чтобы добавить еще больше функций или новых типов среда выполнения Windows в компонент среда выполнения Windows C++/WinRT, можно следовать тем же шаблонам, которые показаны выше. Сначала используйте IDL, чтобы определить функциональные возможности, которые вы хотите предоставить. Затем выполните сборку проекта в Visual Studio, чтобы создать реализацию заглушки. Затем завершите реализацию соответствующим образом. Все методы, свойства и события, определенные в IDL, видны приложению, которое использует компонент среда выполнения Windows. Дополнительные сведения об IDL см. в статье Введение в язык определения интерфейса Майкрософт 3.0.

Пример добавления события в компонент среда выполнения Windows см. в статье Создание событий в C++/WinRT.

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

Симптом Средство
В приложении C++/WinRT, при работе с компонентом C# среды выполнения Windows, который использует XAML, компилятор создает ошибку в форме "'MyNamespace_XaRuntime componentmlTypeInfo': не является членом 'winrt::MyNamespace'"— где MyNamespace — имя пространства имен компонента среды выполнения Windows. В pch.hфайле используемого приложения C++/WinRT, добавьте #include <winrt/MyNamespace.MyNamespace_XamlTypeInfo.h>, заменив MyNamespace соответствующим образом.