Posted on 31. March 2020

Подключение проекта C ++ / CLI к .NET Core

 

Одной из новых функций Visual Studio 2019 (начиная с версии 16.4) и .NET Core 3.1 является возможность создавать проекты C ++ / CLI, ориентированные на .NET Core. Это можно сделать напрямую с помощью cl.exe и link.exe (с использованием новой опции  /clr:netcore) или с помощью MSBuild (с помощью NetCore ). В этой статье я расскажу о шагах, необходимых для переноса простого проекта взаимодействия C ++ / CLI в .NET Core. Более подробную информацию можно найти в документации .NET Core.

Пример проекта

Во-первых, мне нужно сделать пример решения для миграции. Я собираюсь использовать приложение с собственной точкой входа, которая отображает форму Windows Forms через C ++ / CLI. Миграция решения с управляемой точкой входа, взаимодействующей с коренными зависимостями через C ++ / CLI, была бы такой же простой. Для начала я создал решение с тремя проектами:

1. NativeApp. Приложение C ++ для Windows из шаблона Visual Studio «Настольное приложение Windows».

1. Это будет точкой входа в приложение.

2. Я обновил его, чтобы он отображал управляемую форму (через проект CppCliInterop) и вызывал для нее метод при вызове команды IDM_ABOUT.

2. ManagedLibrary. Библиотека C # Windows Forms для .NET Core.

1. Это обеспечит форму WinForms для отображения собственного приложения.

2. Я добавил текстовое поле в форму и метод для установки текста текстового поля. Я также нацелил этот проект на .NET Core и .NET Framework, чтобы его можно было использовать с любым из них. Таким образом, мы можем сосредоточиться на переносе только части образца C ++ / CLI.

3. CppCliInterop. Библиотека .NET Framework C ++ / CLI.

1. Это будет использоваться в качестве уровня взаимодействия для подключения приложения к управляемой библиотеке WinForms.

2. Он ссылается на ManagedLibrary и позволяет коренным проектам использовать его.

3. Это проект, который необходимо перенести в .NET Core.

 

Пример кода доступен на GitHub. При запуске приложения, если вы щелкнете по меню Справка -> О программе, форма WinForms будет отображаться с текстом в текстовом поле, предоставленном проектом NativeApp.

Миграция vcxproj в .NET Core

Теперь для интересной части - обновление примера приложения для запуска на .NET Core. Необходимые изменения на самом деле минимальные. Если вы ранее переносили проекты C # в .NET Core, перенос проектов C ++ / CLI еще проще, поскольку формат файла проекта не меняется. В управляемых проектах проекты .NET Core и .NET Standard используют новый формат файла проекта в стиле SDK. Однако для проектов C ++ / CLI тот же формат vcxproj используется для таргетинга на .NET Core, как и .NET Framework.

Все, что нужно, - это внести несколько изменений в файл проекта. Некоторые из них могут быть сделаны через Visual Studio IDE, но другие (такие как добавление ссылок на WinForms) еще не могут быть. Таким образом, самый простой способ обновить файл проекта - это просто выгрузить проект в VS и отредактировать vcxproj напрямую или использовать редактор, такой как VS Code или Notepad.

1. Замените true на NetCore. Это говорит компилятору использовать /clr:netcore вместо /clr при сборке.

1. Это изменение может быть сделано через интерфейс конфигурации проекта Visual Studio, если вы предпочитаете.

2. Обратите внимание, что указывается отдельно в каждой группе свойств конфигурации / платформы в файле проекта примера проекта, поэтому обновление необходимо выполнить в четырех разных местах.

2. Замените 4.7 на netcoreapp3.1.

1. Эти параметры можно изменить с помощью интерфейса конфигурации проекта Visual Studio на вкладке «Дополнительно». Однако обратите внимание, что изменение параметра поддержки CLR проекта, как описано в предыдущем шаге, не приведет к автоматическому изменению  , поэтому обязательно очистите параметр «.NET Target Framework Version» перед выбором .NET Core Runtime Support.

3. Замените ссылки .NET Framework (на System, System.Data, System.Windows.Forms и System.Xml) следующей ссылкой на компоненты WinForms из Windows Desktop .NET Core SDK. Этот шаг пока не поддерживает Visual Studio IDE, поэтому его необходимо выполнить, отредактировав vcxproj напрямую. Обратите внимание, что необходима только ссылка на Windows Desktop SDK, поскольку .NET Core SDK (который включает в себя такие библиотеки, как System, System.Xml и т. Д.) Включается автоматически. Существуют разные ссылки на Framework для WinForms, WPF или обоих (как описано в документах по миграции).

1.  

После внесения этих изменений проект C ++ / CLI будет успешно ориентирован на .NET Core.

Если вы используете последнюю версию Visual Studio 2019 (16.5 или 16.6 Preview 1), все должно работать и во время выполнения.

До предварительного просмотра Visual Studio 2019 16.5 2 библиотеки C ++ / CLI не создавались файл .runtimeconfig.json, необходимый для библиотек C ++ / CLI, чтобы указать, какую версию .NET Core они используют, поэтому его нужно было добавить вручную. Итак, если вы используете более старую версию Visual Studio, вам нужно будет вручную создать этот файл CppCliInterop.runtimeconfig.json и убедиться, что он скопирован в выходной каталог:

Теперь приложение может работать на .NET Core! Версия источника доступна в  the NetCore branch в репозитории GitHub. Вот форма Windows, запущенная перед загруженными модулями, показывающая выгруженный coreclr.dll.

Билд без MSBui

Миграция этого примера приложения в .NET Core была просто вопросом обновления файла проекта для целевой платформы .NET Core вместо .NET Framework. Если вам нужно собирать сборки C ++ / CLI напрямую с помощью cl.exe и link.exe. Необходимые шаги:

1. Используйте /clr:netcore вместо /clr при вызове cl.exe.

2. Справочные сборки .NET Core с использованием необходимой ссылки /FU (справочные сборки .NET Core обычно устанавливаются в папку % ProgramFiles% \ dotnet \ packs \ \ \ ref).

3. При компоновке включайте каталог хоста приложения .NET Core как LibPath. Хост-файлы приложения .NET Core обычно устанавливаются в папку % Program Files% \ dotnet \ package \ Microsoft.NETCore.App.Host.win-x64 \ \ runtime \ win-x64 \ native).

4. Убедитесь, что файл ijwhost.dll (необходимый для запуска среды выполнения .NET Core) скопирован локально из расположения узла приложения .NET Core. MSBuild делает это автоматически при сборке проекта vcxproj.

5. Создайте файл .runtimeconfig.json, как говорилось ранее.

Несколько предостережений

1. Как видите, с Visual Studio 2019 и .NET Core 3.1 направленность  на .NET Core с проектами C ++ / CLI легко. Однако есть несколько ограничений C ++ / CLI. Поддержка C ++ / CLI возможна только в Windows, даже при работе в .NET Core. Если вам нужна межплатформенная совместимость, ссылайтесь на платформу.

2. Проекты C ++ / CLI не могут быть нацелены на .NET Standard - только .NET Core или .NET Framework - и многоцелевой таргетинг не поддерживается, поэтому для создания библиотеки, которая будет использоваться как вызывающими .NET Framework, так и .NET Core, потребуются два файла проекта.

3. Если в проекте используются API, которые недоступны в .NET Core, эти вызовы необходимо будет обновить до альтернатив .NET Core. .NET Portability Analyzer может помочь найти любые зависимости Framework, которые не будут работать в .NET Core.

Подведение итогов и ресурсы

Надеемся, что в этом примере показано, как воспользоваться преимуществами новой функциональности в Visual Studio 2019 и .NET Core 3.1 для переноса проектов C ++ / CLI в .NET Core. Следующие ссылки могут быть полезны для дальнейшего чтения.

C++/CLI .NET Core migration docs

Пример, использований в этом посте (исходный пример находится в основной ветке, а обновления .NET Core - в ветви netcore)

.NET Portability Analyzer

Источник