Пошаговое руководство. Сборка и импорт блоков заголовков в Microsoft Visual C++
В этой статье описывается создание и импорт блоков заголовков с помощью Visual Studio 2022. Сведения о импорте заголовков стандартной библиотеки C++ в виде блоков заголовков см. в пошаговом руководстве. Импорт библиотек STL в виде единиц заголовка. Более быстрый и надежный способ импорта стандартной библиотеки см. в руководстве по импорту стандартной библиотеки C++ с помощью модулей.
В качестве альтернативы файлам предкомпилированных заголовков (PCH) рекомендуется использовать блоки заголовков. Единицы заголовков проще настроить и использовать, значительно меньше на диске, обеспечивают аналогичные преимущества производительности и являются более гибкими, чем общий PCH.
Чтобы контрастировать блоки заголовков с другими способами включения функциональных возможностей в программы, см . раздел «Сравнение единиц заголовков», модулей и предварительно скомпилированных заголовков.
Необходимые компоненты
Для использования блоков заголовков требуется Visual Studio 2019 версии 16.10 или более поздней.
Что такое блок заголовка
Блок заголовка — это двоичное представление файла заголовка. Блок заголовка заканчивается расширением .ifc . Тот же формат используется для именованных модулей.
Важное различие между единицей заголовка и файлом заголовка заключается в том, что блок заголовка не влияет на определения макросов за пределами единицы заголовка. То есть нельзя определить символ препроцессора, который приводит к тому, что блок заголовка будет вести себя по-разному. К тому времени, когда вы импортируете блок заголовка, блок заголовка уже компилируется. Это отличается от способа #include обработки файла. Включенный файл может повлиять на определение макроса вне файла заголовка, так как файл заголовка проходит через препроцессор при компиляции исходного файла, который включает его.
Блоки заголовков можно импортировать в любом порядке, что не относится к файлам заголовков. Порядок файлов заголовков имеет значение, так как определения макросов, определенные в одном файле заголовка, могут повлиять на последующий файл заголовка. Определения макросов в одной единице заголовка не могут повлиять на другую единицу заголовка.
Все, видимое из файла заголовка, также отображается из единицы заголовка, включая макросы, определенные в единице заголовка.
Перед импортом файла заголовка необходимо преобразовать в блок заголовка. Преимущество блоков заголовков над предварительно скомпилированных файлов заголовков (PCH) заключается в том, что они могут использоваться в распределенных сборках. Пока вы компилируете и программу, импортируемую с тем же компилятором, и нацелив .ifc на ту же платформу и архитектуру, единицу заголовка, созданную на одном компьютере, можно использовать на другом. В отличие от PCH, когда единица заголовка изменяется, только она и то, что зависит от нее, перестроены. Единицы заголовков могут быть до порядка величины меньше размера, чем единица .pch .
Единицы заголовков накладывают меньше ограничений на необходимые сходства сочетаний коммутаторов компилятора, используемых для создания единицы заголовка и компиляции кода, который использует его, чем PCH. Однако некоторые сочетания коммутаторов и определения макросов могут создавать нарушения одного правила определения (ODR) между различными единицами перевода.
Наконец, единицы заголовков являются более гибкими, чем PCH. С помощью PCH вы не можете использовать только один из заголовков в PCH-компиляторе все из них. С блоками заголовков даже при компиляции их в статическую библиотеку вы переносите только содержимое единицы заголовка, импортируемой в приложение.
Блоки заголовков — это шаг между файлами заголовков и модулями C++ 20. Они предоставляют некоторые преимущества модулей. Они более надежны, так как внешние определения макросов не влияют на них, поэтому их можно импортировать в любом порядке. И компилятор может обрабатывать их быстрее, чем файлы заголовков. Но единицы заголовков не имеют всех преимуществ модулей, так как блоки заголовков предоставляют макросы, определенные в них (модули не имеют). В отличие от модулей, нет способа скрыть частную реализацию в блоке заголовков. Чтобы указать частную реализацию с файлами заголовков, используются различные методы, такие как добавление символов подчеркивания в имена или размещение в пространстве имен реализации. Модуль не предоставляет частную реализацию в какой-либо форме, поэтому это не нужно делать.
Попробуйте заменить предварительно скомпилированные заголовки единицами заголовков. Вы получаете то же преимущество скорости, но с другими преимуществами гигиены и гибкости кода, а также.
Способы компиляции блока заголовка
Существует несколько способов компиляции файла в блок заголовка:
- Создание проекта с общим заголовком. Мы рекомендуем этот подход, так как он обеспечивает больший контроль над организацией и повторное использование импортированных единиц заголовков. Создайте проект статической библиотеки, содержащий нужные блоки заголовков, а затем со ссылкой на него, чтобы импортировать единицы заголовков. Пошаговое руководство по этому подходу см. в разделе «Создание проекта статической библиотеки блока заголовка» для единиц заголовков.
- Выберите отдельные файлы для преобразования в блоки заголовков. Этот подход позволяет управлять тем, что рассматривается как единица заголовка. Это также полезно, если необходимо скомпилировать файл как блок заголовка, так как он не имеет расширения по умолчанию ( .ixx , .cppm , , .h ), .hpp обычно не будет компилироваться в единицу заголовка. Именно этот подход демонстрируется в этом пошаговом руководстве. Сведения о начале работы см. в разделе «Подход 1. Перевод определенного файла в единицу заголовка».
- Автоматически сканировать и создавать блоки заголовков. Этот подход удобнее, но лучше всего подходит для небольших проектов, так как он не гарантирует оптимальную пропускную способность сборки. Дополнительные сведения об этом подходе см . в разделе «Подход 2. Автоматическое сканирование единиц заголовка».
- Как упоминание в этой статье, вы можете создавать и импортировать файлы заголовков STL в виде единиц заголовков и автоматически обрабатывать #include заголовки библиотек STL как import без перезаписи кода. Чтобы узнать, как это сделать, посетите пошаговое руководство. Импорт библиотек STL в качестве единиц заголовка.
Подход 1. Перевод определенного файла в единицу заголовка
В этом разделе показано, как выбрать конкретный файл для преобразования в единицу заголовка. Скомпилируйте файл заголовка в виде единицы заголовка, выполнив следующие действия в Visual Studio:
- Создайте проект консольного приложения С++.
- Замените содержимое исходного файла следующим кодом:
#include "Pythagorean.h" int main()
#ifndef PYTHAGOREAN #define PYTHAGOREAN #include inline void PrintPythagoreanTriple(int a, int b) < std::cout #endif
Настройка свойств проекта
Чтобы включить блоки заголовков, сначала задайте для языка C++ стандартный или /std:c++20 более поздней версии следующие действия:
- В Обозреватель решений щелкните правой кнопкой мыши имя проекта и выберите "Свойства".
- В левой области окна страницы со свойствами проекта выберите Свойства конфигурации>Общие.
- В раскрывающемся списке C++ Language Standard выберите ISO C++20 Standard (/std:c++20) или более поздней версии. Нажмите кнопку "ОК", чтобы закрыть диалоговое окно.
Скомпилируйте файл заголовка в виде единицы заголовка:
- В Обозреватель решений выберите файл, который нужно скомпилировать как блок заголовка (в данном случае Pythagorean.h ). Щелкните файл правой кнопкой мыши и выберите пункт "Свойства".
- Задайте раскрывающийся список свойств>конфигурации общего>типа элемента компилятором C/C++ и нажмите кнопку "ОК".
При сборке этого проекта далее в этом пошаговом руководстве Pythagorean.h будет переведено в блок заголовка. Он преобразуется в единицу заголовка, так как тип элемента для этого файла заголовка имеет значение компилятор C/C++, и так как действие по умолчанию для .h и .hpp файлов, заданных таким образом, заключается в переводе файла в единицу заголовка.

Изменение кода для импорта единицы заголовка
- В исходном файле примера проекта измените значение #include "Pythagorean.h" не import "Pythagorean.h"; забывайте о запятой. Это необходимо для import инструкций. Так как это файл заголовка в локальном каталоге проекта, мы использовали кавычки с инструкцией import : import "file"; В собственных проектах для компиляции единицы заголовка из системного заголовка используйте угловые скобки: import ;
- Скомпилируйте решение, выбрав Сборка>Собрать решение в главном меню. Запустите его, чтобы увидеть, что он создает ожидаемые выходные данные: Pythagorean triple a:2 b:3 c:13
В собственных проектах повторите эту процедуру, чтобы скомпилировать файлы заголовков, которые нужно импортировать в качестве блоков заголовков.
Если вы хотите преобразовать только несколько файлов заголовков в единицы заголовков, этот подход подходит. Но если у вас есть много файлов заголовков, которые вы хотите скомпилировать, и потенциальная потеря производительности сборки перевешивается удобством автоматической обработки системы сборки, см. следующий раздел.
Если вы хотите специально импортировать заголовки библиотек STL в качестве единиц заголовков, см . пошаговое руководство. Импорт библиотек STL в качестве единиц заголовка.
Подход 2. Автоматическое сканирование и блоки заголовков сборки
Так как требуется время для сканирования всех исходных файлов для единиц заголовков и времени их сборки, следующий подход лучше подходит для небольших проектов. Это не гарантирует оптимальную пропускную способность сборки.
Этот подход объединяет два параметра проекта Visual Studio:
- Источники сканирования для зависимостей модулей вызывают систему сборки для вызова компилятора, чтобы убедиться, что все импортированные модули и блоки заголовков создаются перед компиляцией файлов, зависящих от них. При сочетании с преобразованием "Включает в импорт" все файлы заголовков, включенные в источник, которые также указаны в header-units.json файле, расположенном в том же каталоге, что и файл заголовка, компилируются в единицы заголовков.
- Преобразование "Включает в импорт " обрабатывает файл заголовка как import файл заголовка, если #include он ссылается на файл заголовка, который можно скомпилировать как единицу заголовка (как указано в header-units.json файле), а скомпилированный блок заголовка доступен для файла заголовка. В противном случае файл заголовка рассматривается как обычный #include . Файл header-units.json используется для автоматической сборки блоков заголовков для каждого #include из них без дублирования символов.
Эти параметры можно включить в свойствах проекта. Для этого щелкните проект правой кнопкой мыши в Обозреватель решений и выберите "Свойства". Затем выберите свойства>конфигурации C/C++>General.

Источники сканирования для зависимостей модуля можно задать для всех файлов проекта в свойствах проекта, как показано здесь, или для отдельных файлов в свойствах файла. Модули и блоки заголовков всегда сканируются. Установите этот параметр, если у вас есть .cpp файл, который импортирует блоки заголовков, которые вы хотите создать автоматически и может еще не создаваться.
Эти параметры работают вместе, чтобы автоматически создавать и импортировать блоки заголовков в следующих условиях:
- Источники сканирования для зависимостей модуля сканируют источники файлов и их зависимостей, которые можно рассматривать как единицы заголовков. Файлы с расширением .ixx и файлами с их свойствами>файла C/C++>Compile As, заданными для компиляции как единица заголовка C++ (/export), всегда сканируются независимо от этого параметра. Компилятор также ищет import инструкции для идентификации зависимостей единиц заголовка. Если /translateInclude задано, компилятор также проверяет #include директивы, которые также указаны в header-units.json файле для обработки как единиц заголовка. Граф зависимостей создается из всех модулей и блоков заголовков в проекте.
- Перевод включает в импорт , когда компилятор обнаруживает #include инструкцию, и соответствующий файл единицы заголовка существует .ifc для указанного файла заголовка, компилятор импортирует единицу заголовка вместо того, чтобы рассматривать файл заголовка как файл заголовка #include . В сочетании с сканированием зависимостей компилятор находит все файлы заголовков, которые можно скомпилировать в единицы заголовков. Список разрешений обращается к компилятору, чтобы решить, какие файлы заголовков могут компилироваться в единицы заголовков. Этот список хранится в header-units.json файле, который должен находиться в том же каталоге, что и включенный файл. Пример header-units.json файла можно просмотреть в каталоге установки для Visual Studio. Например, компилятор используется для определения того, %ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.30.30705\include\header-units.json можно ли компилировать заголовок стандартной библиотеки шаблонов в единицу заголовка. Эта функция существует, чтобы служить мостом с устаревшим кодом, чтобы получить некоторые преимущества единиц заголовков.
Файл header-units.json служит двумя целями. Помимо указания файлов заголовков, которые можно скомпилировать в единицы заголовков, он сводит к минимуму повторяющиеся символы для повышения пропускной способности сборки. Дополнительные сведения о дублировании символов см . в справочнике по C++ header-units.json.
Эти коммутаторы и header-unit.json некоторые преимущества единиц заголовка. Удобство приходит за счет пропускной способности сборки. Этот подход может быть не лучшим для крупных проектов, так как он не гарантирует оптимальное время сборки. Кроме того, те же файлы заголовков могут повторно обрабатываться повторно, что увеличивает время сборки. Однако удобство может быть стоит в зависимости от проекта.
Эти функции предназначены для устаревшего кода. Для нового кода перейдите к модулям вместо единиц заголовков или #include файлов. Руководство по использованию модулей см. в руководстве по модулям имен (C++).
Пример использования этого метода для импорта файлов заголовков STL в виде единиц заголовка см. в пошаговом руководстве. Импорт библиотек STL в качестве единиц заголовка.
Последствия препроцессора
Стандартный препроцессор C99/C++11 требуется для создания и использования единиц заголовков. Компилятор включает новый препроцессор C99/C++11 при компиляции блоков заголовков путем неявного добавления /Zc:preprocessor в командную строку при использовании любой /exportHeader формы. Попытка отключить ее приведет к ошибке компиляции.
Включение нового препроцессора влияет на обработку виртуальных макросов. Дополнительные сведения см. в разделе примечания к макросам Variadic.
Обновление расширения Visual Studio для Visual Studio 2022
Область применения:
Visual Studio Visual Studio для Mac
Visual Studio Code ![]()
Советы, приведенные в этой статье, позволяют разработчикам переносить расширения, требующие значительных изменений в Visual Studio 2019 и Visual Studio 2022. В этих случаях рекомендуется использовать два проекта VSIX и условную компиляцию.
Многие расширения будут работать как в Visual Studio 2019, так и в Visual Studio 2022 с незначительными изменениями, которые не требуют выполнения рекомендаций по модернизации расширения в этой статье. Попробуйте использовать расширение в Visual Studio 2022 и оцените, какой вариант лучше всего подходит для расширения.
Visual Studio 2022 — это 64-разрядное приложение, которое представляет собой критические изменения в пакете SDK Для Visual Studio. В этой статье описаны действия, необходимые для работы расширения с текущей предварительной версией Visual Studio 2022. После этого расширение можно подготовить для пользователей, которые будут устанавливаться до достижения общедоступной доступности Visual Studio 2022.
Установка расширений Visual Studio и компиляция
Установите Visual Studio 2022 из скачивания Visual Studio 2022.
Расширения, написанные на языке .NET
Пакет SDK Visual Studio, предназначенный для Visual Studio 2022 для управляемых расширений, предназначен исключительно для NuGet:
- Метапакет Microsoft.VisualStudio.Sdk (версии 17.x) приносит большинство или все необходимые эталонные сборки.
- Пакет Microsoft.VSSDK.BuildTools (версии 17.x) должен ссылаться из проекта VSIX, чтобы он смог создать visual Studio 2022-совместимый VSIX.
Даже если вы не ссылаетесь на критические изменения, расширения должны быть скомпилированы с любой платформой ЦП или x64 . Платформа x86 несовместима с 64-разрядным процессом в Visual Studio 2022.
Расширения, написанные на C++
Пакет SDK Visual Studio для расширений, скомпилированных с помощью C++, доступен с установленным пакетом SDK Visual Studio, как обычно.
Даже если вы не ссылаетесь на критические изменения, расширения должны быть скомпилированы специально для пакета SDK Для Visual Studio 2022 и для AMD64.
Расширения с запущенным кодом
Расширения с запущенным кодом необходимо скомпилировать специально для Visual Studio 2022. Visual Studio 2022 не загружает любое расширение, предназначенное для более ранней версии Visual Studio.
Узнайте, как перенести расширения для более ранних версий Visual Studio в Visual Studio 2022:
- Модернизация проектов.
- Рефакторинг исходного кода в общий проект , позволяющий использовать Visual Studio 2022 и более ранние версии.
- Добавьте проект VSIX, предназначенный для Visual Studio 2022, и таблицу повторного сопоставления пакетов или сборок.
- Внесите необходимые корректировки кода.
- Проверьте расширение Visual Studio 2022.
- Опубликуйте расширение Visual Studio 2022.
Расширения без выполнения кода
Расширения, которые не содержат выполняющийся код (например, шаблоны проектов или элементов), не требуются для выполнения предыдущих шагов, включая производство двух отдельных VSIX.
Вместо этого измените один VSIX, чтобы его source.extension.vsixmanifest файл объявил два целевых объекта установки:
x86 amd64
Инструкции, описанные в этой статье, можно пропустить с помощью общих проектов и нескольких VSIX. Вы можете продолжить тестирование.
Если вы создаете новое расширение Visual Studio с помощью Visual Studio 2022, а также хотите использовать Visual Studio 2019 или более раннюю версию, ознакомьтесь с этим руководством.
задачи MSBuild
Если вы создаете задачи MSBuild, помните, что в Visual Studio 2022 вероятно, что они будут загружены в 64-разрядном процессе MSBuild.exe. Если для выполнения задачи требуется 32-разрядный процесс, см. статью "Настройка целевых объектов и задач ", чтобы убедиться, что MSBuild загружает задачу в 32-разрядном процессе.
Модернизация проекта VSIX
Прежде чем добавлять поддержку Visual Studio 2022 в расширение, настоятельно рекомендуется очистить и модернизировать существующий проект:
- Миграция из packages.config в PackageReference .
- Замените все прямые ссылки на сборки пакета SDK Для Visual Studio элементами PackageReference :
Совет Можно заменить множество ссылок на сборку только одним PackageReference экземпляром для метапакета:
Некоторые сборки, которые не являются уникальными для пакета SDK Visual Studio (например, Newtonsoft.Json.dll), могут быть обнаружены с помощью простой ссылки до Visual Studio 2022. Но в Visual Studio 2022 вместо этого им требуется ссылка на пакет. Причина в том, что некоторые каталоги среды выполнения и пакета SDK Visual Studio были удалены из пути поиска сборки по умолчанию в MSBuild.
При переключении с прямых ссылок на сборки на ссылки на пакеты NuGet можно получить дополнительные ссылки на сборки и пакеты анализаторов, так как NuGet автоматически устанавливает транзитивное закрытие зависимостей. Обычно это нормально, но это может привести к дополнительным предупреждениям во время сборки. Выполните эти предупреждения и устраните столько, сколько вы можете. Рассмотрите возможность использования регионов в коде #pragma warning disable для подавления предупреждений, которые невозможно устранить.
Использование общих проектов для многонацеливания
Общие проекты — это тип проекта, представленный в Visual Studio 2015. Общие проекты в Visual Studio позволяют совместно использовать файлы исходного кода между несколькими проектами и создавать по-разному с помощью символов условной компиляции и уникальных наборов ссылок.
Для Visual Studio 2022 требуется отдельный набор ссылочных сборок из всех предыдущих версий Visual Studio. Поэтому рекомендуется использовать общие проекты для удобного многоцеляного расширения в Visual Studio 2022, более ранних версиях и более поздних версиях. Этот метод дает общий доступ к коду, но различные ссылки.
В контексте расширений Visual Studio можно использовать один проект VSIX для Visual Studio 2022 и более поздней версии, а также один проект VSIX для Visual Studio 2019 и более ранних версий. Каждый из этих проектов содержит только source.extension.vsixmanifest экземпляр и ссылки на пакет либо пакет SDK 16.x, либо пакет SDK 17.x. Эти проекты VSIX также будут иметь общую ссылку на проект, который будет размещать весь исходный код, который может использоваться в двух версиях Visual Studio.
В этом разделе предполагается, что у вас уже есть проект VSIX, предназначенный для Visual Studio 2019, и вы хотите, чтобы расширение работало в Visual Studio 2022.
Все эти действия можно выполнить с помощью Visual Studio 2019:
- Если вы еще этого не сделали, модернизируйте проекты, чтобы упростить шаги позже в этом процессе обновления.
- Добавьте новый общий проект в решение для каждого существующего проекта, ссылающегося на пакет SDK Visual Studio. Щелкните правой кнопкой мыши решение и выберите команду "Добавить >новый проект".

- В диалоговом окне "Добавление нового проекта" найдите общий проект и выберите шаблон общего проекта.

- Добавьте ссылку из каждого проекта пакета SDK для Visual Studio, ссылающегося на его общий проект.

- Переместите весь исходный код (включая CS-файлы и RESX-файлы ) из каждого проекта SDK Для Visual Studio, ссылающегося на его общий проект. Оставьте файл source.extension.vsixmanifest в проекте VSIX.

- Переместите файлы метаданных (например, заметки о выпуске, лицензию и значки) и файлы VSCT в общий каталог. Затем добавьте их в виде связанных файлов в проект VSIX. Обратите внимание, что общий каталог отделен от общего проекта.
- Для файлов метаданных задайте для действия сборки содержимое . Задайте значение "Включить" в VSIX значение True.

- Для vsCT-файлов задайте действиесборки в VSCTCompile. Задайте значение "Включить" в VSIX значение False.
Если Visual Studio жалуется, что этот параметр не поддерживается, можно вручную изменить действие сборки, выгрузив проект и изменив его на Content VSCTCompile :
- - VSIXProject1Package.vsct - + + VSIXProject1Package.vsct + Menus.ctmenu +
Теперь проект готов к добавлению поддержки Visual Studio 2022.
Добавление целевого объекта Visual Studio 2022
В этом разделе предполагается, что вы выполнили действия по фактору расширения Visual Studio с общими проектами.
Добавьте поддержку Visual Studio 2022 в расширение, выполнив следующие действия. Их можно выполнить с помощью Visual Studio 2019.

- Добавьте новый проект VSIX в решение. Этот проект предназначен для Visual Studio 2022. Удалите любой исходный код, который пришел с шаблоном, но сохраните файл source.extension.vsixmanifest .
- В новом проекте VSIX добавьте ссылку на тот же общий проект, на который ссылается Visual Studio 2019.
- Убедитесь, что новый проект VSIX правильно выполняет сборку. Для устранения ошибок компилятора может потребоваться добавить ссылки на соответствие исходному проекту VSIX.
- Для управляемых расширений Visual Studio обновите ссылки на пакет с версии 16.x (или более ранних версий) до версий пакетов 17.x в файле проекта, ориентированном на Visual Studio 2022. Используйте диспетчер пакетов NuGet или непосредственно измените файл проекта:
amd64
Важно! В Visual Studio 2019 конструктор этого файла не предоставляет новый ProductArchitecture элемент. Чтобы внести это изменение, необходимо использовать редактор XML. Чтобы получить доступ к редактору XML, перейдите к Обозреватель решений и выберите команду "Открыть с помощью". Элемент ProductArchitecture является критическим. Visual Studio 2022 не установит расширение без него.
На этом этапе у вас есть расширение VSIX для Visual Studio 2022. Вы должны создать проект VSIX для Visual Studio 2022 и работать с любыми разрывами сборки, которые отображаются. Если у вас нет разрывов сборки в проекте VSIX, ориентированном на Visual Studio 2022, поздравляем! Вы готовы к тестированию.
Обработка критических изменений API
Критические изменения API могут требовать обновления кода, запущенного в более ранних версиях Visual Studio. Советы по обновлению кода см. в статье "Критические изменения API" в Visual Studio 2022.
При адаптации кода рекомендуется использовать условную компиляцию. Затем код может продолжать поддерживать более ранние версии Visual Studio при добавлении поддержки Visual Studio 2022.
Когда вы получаете сборку расширений, предназначенных для Visual Studio 2022, перейдите к тестированию .
Использование символов условной компиляции
Если вы хотите использовать тот же исходный код, даже один и тот же файл для Visual Studio 2022 и более ранних версий, может потребоваться использовать условную компиляцию. Затем вы можете ввести вилку кода, чтобы адаптироваться к критическим изменениям. Условная компиляция — это функция языков C#, Visual Basic и C++. Его можно использовать для совместного использования большинства кода при совместном использовании разных API в определенных местах.
Дополнительные сведения об использовании директив препроцессора и символов условной компиляции см . в директивах препроцессора C#.
Для проектов, предназначенных для более ранних версий Visual Studio, потребуется условный символ компиляции. Затем этот символ можно использовать для вилки кода для использования различных API. На странице свойств проекта можно задать символ условной компиляции:

Не забудьте задать символ компиляции для всех конфигураций. По умолчанию символ, который вы вводите, может применяться только к одной конфигурации.
Методы C#
Символ компиляции можно использовать в качестве директивы препроцессора ( #if ), как показано в следующем коде. Затем можно ввести вилку кода, чтобы справиться с критическим изменением между версиями Visual Studio.
Guid myGuid = new Guid(""); uint myFlags = 0; IVsShell shell = await AsyncServiceProvider.GlobalProvider.GetServiceAsync(); #if Dev16 shell.LoadUILibrary(myGuid, myFlags, out uint ptrLib); #else shell.LoadUILibrary(myGuid, myFlags, out IntPtr ptrLib); #endif
В некоторых случаях можно избежать var именования типа и избежать необходимости в #if регионах. Предыдущий фрагмент кода также можно написать следующим образом:
Guid myGuid = new Guid(""); uint myFlags = 0; IVsShell shell = await AsyncServiceProvider.GlobalProvider.GetServiceAsync(); shell.LoadUILibrary(myGuid, myFlags, out var ptrLib);
При использовании синтаксиса #if обратите внимание, как использовать раскрывающийся список для контекста службы языка для изменения выделения синтаксиса. Другой раскрывающийся список помогает службе языков сосредоточить внимание на одной целевой версии Visual Studio для этого расширения и другого.

Методы совместного использования XAML
XAML не имеет препроцессора, чтобы разрешить настройку содержимого на основе символов препроцессора. Может потребоваться скопировать и сохранить две страницы XAML, содержимое которых отличается от Visual Studio 2022 и более ранних версий.
В некоторых случаях ссылка на тип, который существует в разных сборках в Visual Studio 2022 и более ранних версиях, по-прежнему может быть представлена в одном XAML-файле. Удалите пространство имен, ссылающееся на сборку:
-xmlns:vsui="clr-namespace:Microsoft.VisualStudio.PlatformUI;assembly=Microsoft.VisualStudio.Shell.14.0" -Value=">" +Value=""
Тестирование расширения
Чтобы протестировать расширение, предназначенное для Visual Studio 2022, необходимо установить Visual Studio 2022. Вы не сможете запускать 64-разрядные расширения в более ранних версиях Visual Studio.
Вы можете использовать Visual Studio 2022 для создания и тестирования расширений, предназначенных для Visual Studio 2022 или более ранней версии. При открытии проекта VSIX из Visual Studio 2022 откроется экспериментальный экземпляр Visual Studio.
Настоятельно рекомендуется протестировать каждую версию Visual Studio, которую требуется поддерживать расширение.
Публикация расширения
Вы добавили целевой объект Visual Studio 2022 в расширение и проверили его. Теперь вы готовы опубликовать расширение для мира, чтобы восхищаться.
Visual Studio Marketplace
Публикация расширения в Visual Studio Marketplace — отличный способ получить новых пользователей для поиска и установки расширения. Независимо от того, предназначено ли ваше расширение к Visual Studio 2022 исключительно или предназначено для более старых версий Visual Studio, Marketplace поддерживает вас.
В будущем Marketplace позволит передать несколько VSIX в только один список Marketplace. Затем вы можете отправить visual Studio 2022 с целевой версией VSIX и VSIX для более ранней версии Visual Studio. Пользователи автоматически получат правильную версию VSIX для установленной версии Visual Studio при использовании диспетчера расширений Visual Studio.
Настраиваемый установщик
Если вы создаете MSI-файл или EXE для установки расширения и создаете vsixinstaller.exe его для установки (часть) расширения, знают, что установщик VSIX в Visual Studio 2022 был обновлен. Разработчикам необходимо использовать версию установщика VSIX, которая поставляется с Visual Studio 2022 для установки расширений в этой версии Visual Studio.
Установщик VSIX в Visual Studio 2022 также устанавливает применимые расширения, предназначенные для предыдущих версий Visual Studio, которые существуют с Visual Studio 2022 на том же компьютере.
Сетевая папка
Вы можете поделиться расширением по локальной сети или другим способом. Если вы нацелены на Visual Studio 2022 и более ранних версий, необходимо совместно использовать несколько VSIX по отдельности. Присвойте им имена файлов (или поместите их в уникальные папки), которые помогают пользователям узнать, какой VSIX необходимо установить на основе установленной версии Visual Studio.
Зависимости
Если vsIX указывает другие VSIX в качестве зависимостей через элемент, каждый из них должен быть установлен в одних и том же целевых объектах и архитектурах продуктов, что и VSIX. Если зависимый VSIX не поддерживает целевую установку Visual Studio, vsIX завершится ошибкой.
Это нормально для зависимой VSIX для поддержки больше целевых объектов и архитектур, чем ваши, просто не меньше. Это ограничение означает, что подход к развертыванию и распределению VSIX с зависимостями должен зеркало его зависимостей.
Вопросы & ответы
Вопрос. Для расширения не требуется никаких изменений взаимодействия, так как он просто предоставляет данные (например, шаблоны). Можно ли создать одно расширение, которое также включает Visual Studio 2022?
Ответ. Да. Сведения об этом см . в расширениях без выполнения кода .
Вопрос. Зависимость NuGet приводит к старым сборкам взаимодействия и вызывает столкновение классов. Что делать?
Ответ. Добавьте следующую строку в CSPROJ-файл , чтобы избежать повторяющихся сборок:
" ExcludeAssets="compile" PrivateAssets="all" />
Этот код не позволит ссылкам на пакеты импортировать старую версию сборки из других зависимостей.
Вопрос. Мои команды и горячие ключи перестали работать в Visual Studio после переключения исходных файлов в общий проект. Что делать?
Ответ. Шаг 2.4 примера оптимизатора изображений показывает, как добавить файлы VSCT в качестве связанных элементов, чтобы они скомпилировались в VSCT-файл.
Следующие шаги
Выполните пошаговый пример ImageOptimizer с ссылками на изменения проекта и кода для каждого шага.
Создание расширения C++ для Python
Область применения:
Visual Studio Visual Studio для Mac
Visual Studio Code ![]()
Модули, написанные на C++ (или C), обычно используются для расширения возможностей интерпретатора Python. Они также обеспечивают доступ к низкоуровневым возможностям операционной системы.
Модули можно разделить на три следующих основных типа.
- Модули ускорения. Так как Python является интерпретируемым языком, вы можете писать модули ускорителя на C++ для повышения производительности.
- Модули-оболочки. Эти модули открывают существующие интерфейсы C/C++ для кода Python или предоставляют адаптированный API, который удобно использовать в Python.
- Модули низкоуровневого системного доступа. Эти модули создаются для доступа к низкоуровневым функциям среды выполнения CPython , операционной системы или базового оборудования.
В этой статье рассматривается создание модуля расширения C++ для CPython , который вычисляет гиперболический тангенс и вызывает его из кода Python. Подпрограмма реализована сначала на языке Python, чтобы продемонстрировать относительный прирост производительности по сравнению с реализацией той же подпрограммы на C++.
В этой статье также показаны два способа сделать расширение C++ доступным в Python:
- использование стандартных расширений CPython , как описано в документации по Python;
- использование PyBind11 (рекомендуется для C++ 11 благодаря его простоте). Для обеспечения совместимости используйте какую-то из более актуальных версий Python.
Полный пример из этого руководства см. на GitHub по ссылке python-samples-vs-cpp-extension.
Необходимые компоненты

- Visual Studio 2017 или более поздней версии с установленной рабочей нагрузкой разработки на Python. Эта рабочая нагрузка включает встроенные средства разработки Python, которые подключают рабочую нагрузку C++ и наборы инструментов, необходимые для собственных расширений.
Примечание. При установке рабочей нагрузки Приложения для обработки и анализа данных и аналитические приложения среда Python и встроенные средства разработки Python устанавливаются по умолчанию.
Дополнительные сведения о параметрах установки см. в разделе Установка поддержки Python в Visual Studio. Если вы устанавливаете Python отдельно, обязательно выберите параметр Скачать отладочные символы в разделе Дополнительные параметры установщика. Этот параметр необходим, чтобы вы могли использовать отладку в смешанном режиме между кодом Python и машинным кодом.
Создание приложения Python
- Создайте проект Python в Visual Studio, выбрав Файл>Создать>Проект.
- Выполните поиск по ключевому слову Python, выберите шаблон Приложение Python, задайте имя и расположение, а затем нажмите кнопку OK.
- В файл проекта с расширением .py вставьте следующий код. Чтобы испытать некоторые функции редактирования Python, попробуйте ввести этот код вручную. Этот код вычислит гиперболический тангенс без использования математической библиотеки, что позволит вам ускорить работу встроенных расширений.
Совет Сначала напишите код только на Python, а затем перепишите его на C++. Таким образом вам будет проще проверить правильность машинного кода.
from random import random from time import perf_counter COUNT = 500000 # Change this value depending on the speed of your computer DATA = [(random() - 0.5) * 3 for _ in range(COUNT)] e = 2.7182818284590452353602874713527 def sinh(x): return (1 - (e ** (-2 * x))) / (2 * (e ** -x)) def cosh(x): return (1 + (e ** (-2 * x))) / (2 * (e ** -x)) def tanh(x): tanh_x = sinh(x) / cosh(x) return tanh_x def test(fn, name): start = perf_counter() result = fn(DATA) duration = perf_counter() - start print('<> took seconds\n\n'.format(name, duration)) for d in result: assert -1 '.format(COUNT)) test(lambda d: [tanh(x) for x in d], '[tanh(x) for x in d] (Python implementation)')
Совет При запуске тестов производительности всегда выбирайте в меню Отладка>Запуск без отладки. Это помогает избежать дополнительных временных затрат, возникающих при запуске кода в отладчике Visual Studio.
Создание основных проектов C++
Следуйте инструкциям в этом разделе, чтобы создать два идентичных проекта C++ с именами superfastcode и superfastcode2. Позднее вы будете использовать в этих проектах разные способы предоставления кода C++ в Python.
- В обозревателе решений щелкните решение правой кнопкой мыши и последовательно выберите пункты Добавить>Новый проект. Решение Visual Studio может одновременно содержать проекты Python и C++ — это одно из преимуществ использования Visual Studio для Python.
- Выполните поиск C++, выберите Пустой проект, укажите либо superfastcode для первого проекта, либо superfastcode2 для второго проекта, а затем нажмите кнопку OK.
Совет Или, если вы установили собственные средства разработки Python в Visual Studio, можете начать с шаблона "Модуль расширения Python". В этом шаблоне уже имеется большая часть описанных здесь возможностей. Но в этом пошаговом руководстве начало работы с пустого проекта позволяет шаг за шагом продемонстрировать создание модуля расширения. Ознакомившись с процессом, в дальнейшем вы сможете использовать этот шаблон для экономии времени при написании собственных расширений.
Важно! Файл с расширением .cpp нужен, чтобы активировать страницы свойств C++ в последующих шагах.
- Для 64-разрядной среды выполнения Python активируйте конфигурацию x64.
- Для 32-разрядной среды выполнения Python следует активировать конфигурацию Win32.
Примечание. При создании собственных проектов вам понадобится настроить конфигурации и отладки, и выпуска. В этом уроке вы настроите только конфигурацию отладки и установите в ней использование сборки выпуска CPython. Эта конфигурация отключает некоторые функции отладки среды выполнения C++, в том числе утверждения. Для использования двоичных файлов отладки CPython (python_d.exe) требуются другие параметры.
Примечание. Если вы не видите вкладку C/C++ в свойствах проекта, значит, в проекте нет файлов, определенных как исходные файлы C/C++. Такая ситуация может возникнуть, если вы создали исходный файл без расширения .c или .cpp. Например, если в диалоговом окне создания элемента вы случайно введете module.coo вместо module.cpp, Visual Studio создаст файл, но не задаст для него тип Код C/C, что требуется для активации вкладки свойств C/C++. Такая неправильная идентификация сохранится, даже если вы переименуете файл и добавите расширение .cpp. Чтобы установить правильный тип файла, в Обозревателе решений щелкните файл правой кнопкой мыши и выберите пункт Свойства. Затем в качестве типа файлавыберите Код C/C++.
#include #include const double e = 2.7182818284590452353602874713527; double sinh_impl(double x) < return (1 - pow(e, (-2 * x))) / (2 * pow(e, -x)); >double cosh_impl(double x) < return (1 + pow(e, (-2 * x))) / (2 * pow(e, -x)); >double tanh_impl(double x) < return sinh_impl(x) / cosh_impl(x); >
Преобразование проекта C++ в расширения для Python
Чтобы преобразовать DLL-библиотеку C++ в расширение для Python, сначала нужно изменить экспортируемые методы для взаимодействия с типами Python. После этого добавьте функцию, экспортирующую модуль, а также определения методов модуля.
В последующих разделах объясняется, как выполнить эти действия с помощью расширений CPython и PyBind11.
Использование расширений CPython
Дополнительные сведения о коде, приведенном в этом разделе, см. в справочном руководстве по API Python/C, в частности на странице Объекты модуля. Не забудьте выбрать версию Python в раскрывающемся списке в правом верхнем углу.
-
В верхней части файла module.cpp включите Python.h.
#include
PyObject* tanh_impl(PyObject* /* unused module reference */, PyObject* o) < double x = PyFloat_AsDouble(o); double tanh_x = sinh_impl(x) / cosh_impl(x); return PyFloat_FromDouble(tanh_x); >
static PyMethodDef superfastcode_methods[] = < // The first property is the name exposed to Python, fast_tanh // The second is the C++ function with the implementation // METH_O means it takes a single PyObject argument < "fast_tanh", (PyCFunction)tanh_impl, METH_O, nullptr >, // Terminate the array with an object containing nulls. < nullptr, nullptr, 0, nullptr >>;
static PyModuleDef superfastcode_module = < PyModuleDef_HEAD_INIT, "superfastcode", // Module name to use with Python import statements "Provides some functions, but faster", // Module description 0, superfastcode_methods // Structure that defines the methods of the module >;
PyMODINIT_FUNC PyInit_superfastcode()
Использование PyBind11
Если вы выполнили действия из предыдущего раздела, вы наверняка заметили, что использовали много стандартного кода для создания необходимых структур модулей для кода C++. PyBind11 упрощает этот процесс с помощью макросов в файле заголовка C++, которые позволяют получить тот же результат с гораздо меньшим объемом кода.
Дополнительные сведения о коде в этом разделе см. в разделе Основы PyBind11.
- Установите PyBind11 с помощью pip: pip install pybind11 или py -m pip install pybind11 . Вы также можете установить PyBind11 с помощью окна "Окружения Python", а затем использовать его команду Открыть в PowerShell для выполнения следующего шага.
- В том же терминале выполните python -m pybind11 --includes или py -m pybind11 --includes . Это действие выводит список путей, которые следует добавить в свойство C/C++>Общие>Дополнительные каталоги включаемых файлов вашего проекта. Обязательно удалите префикс -I , если он присутствует.
- В верхнюю часть нового файла module.cpp, который не содержит изменения из предыдущего раздела, включите pybind11.h.
#include
namespace py = pybind11; PYBIND11_MODULE(superfastcode2, m)
Устранение ошибок компиляции
Модуль C++ может не компилироваться по следующим причинам.
- Ошибка: не удается обнаружить Python.h (E1696: не удается открыть исходный файл Python.h и/или C1083: не удается открыть включаемый файл: Python.h — не существует такого файла или каталога) Решение: проверьте, что путь в разделе C/C++>Общие>Дополнительные каталоги включаемых файлов в свойствах проекта указывает на папку include установки Python. См. шаг 6 в разделе Создание основного проекта C++. Дополнительные сведения о доступе к сведениям о конфигурации установки Python см . в документации по Python.
- Ошибка: не удается обнаружить библиотеки Python Решение: проверьте, что путь в разделе Компоновщик>Общие>Дополнительные каталоги библиотек в свойствах проекта указывает на папку libs установки Python. См. шаг 6 в разделе Создание основного проекта C++. Дополнительные сведения о доступе к сведениям о конфигурации установки Python см . в документации по Python.
- Ошибки компоновщика, связанные с решением целевой архитектуры: измените архитектуру проекта целевого объекта C++ на соответствие архитектуре установки Python. Например, если вы хотите использовать в проекте C++ версию Win32, но у вас установлена версия Python x64, измените проект C++ для работы с версией х64.
Тестирование кода и сравнение результатов
Теперь, когда библиотека DLL структурирована как расширения Python, можно ссылаться на них из проекта Python, импортировать модули и использовать их методы.
Предоставление доступа к библиотеке DLL для Python
Библиотеку DLL можно сделать доступной для Python несколькими способами. Покажем два метода, которые рекомендуется рассмотреть.

- Первый метод работает, если проект Python и проект C++ находятся в одном решении. Выполните следующие действия.
- В Обозревателе решений щелкните правой кнопкой мыши узел Ссылки в вашем проекте Python, а затем выберите команду Добавить ссылку.
- В открывшемся диалоговом окне перейдите на вкладку Проекты, выберите проекты superfastcode и superfastcode2 и нажмите кнопку OK.
- В другом методе устанавливается модуль в вашей среде Python, что делает этот модуль доступным и для других проектов Python. Дополнительные сведения см. в документации по проекту setuptools. Выполните следующие действия.
- Создайте в проекте C++ файл с именем setup.py, щелкнув проект правой кнопкой мыши и выбрав пункт Добавить>Новый элемент.
- Выберите Файл C++ (. cpp), назначьте этому файлу имя setup.py и нажмите кнопку OK. Если файлу назначить имя с расширением .py, это позволяет Visual Studio распознать его как файл Python, несмотря на использование шаблона файла C++. Когда файл откроется в редакторе, вставьте в него следующий код в зависимости от метода расширения. Для расширений CPython (проект superfastcode)
from setuptools import setup, Extension sfc_module = Extension('superfastcode', sources = ['module.cpp']) setup( name='superfastcode', version='1.0', description='Python Package with superfastcode C++ extension', ext_modules=[sfc_module] )
Для PyBind11 (проект superfastcode2)
from setuptools import setup, Extension import pybind11 cpp_args = ['-std=c++11', '-stdlib=libc++', '-mmacosx-version-min=10.7'] sfc_module = Extension( 'superfastcode2', sources=['module.cpp'], include_dirs=[pybind11.get_include()], language='c++', extra_compile_args=cpp_args, ) setup( name='superfastcode2', version='1.0', description='Python package with superfastcode2 C++ extension (PyBind11)', ext_modules=[sfc_module], )
[build-system] requires = ["setuptools", "wheel", "pybind11"] build-backend = "setuptools.build_meta"
Совет Если пакет уже установлен, он появится в списке. Прежде чем продолжить, щелкните значок X, чтобы удалить его.
Совет Если установка завершается неудачно из-за ошибки, связанной с разрешениями, добавьте в конец --user и попробуйте выполнить команду еще раз.
Вызов библиотеки DLL из Python
После того как вы сделаете библиотеки DLL доступными для Python, как описано в предыдущем разделе, можно вызывать функции superfastcode.fast_tanh и superfastcode2.fast_tanh2 из кода Python и сравнивать их эффективность с реализацией Python. Чтобы вызвать библиотеку DLL, выполните следующие действия.
-
Добавьте следующие строки в файл .py, чтобы вызвать методы, экспортированные из библиотек DLL, и отобразить их выходные данные.
from superfastcode import fast_tanh test(lambda d: [fast_tanh(x) for x in d], '[fast_tanh(x) for x in d] (CPython C++ extension)') from superfastcode2 import fast_tanh2 test(lambda d: [fast_tanh2(x) for x in d], '[fast_tanh2(x) for x in d] (PyBind11 C++ extension)')
Примечание. Если команда Запуск без отладки отключена, в Обозревателе решений щелкните правой кнопкой мыши проект Python и выберите команду Назначить запускаемым проектом.
Убедитесь, что подпрограммы C++ выполняются примерно в 5–20 раз быстрее, чем реализация на Python. Обычно выводится следующий результат.
Running benchmarks with COUNT = 500000 [tanh(x) for x in d] (Python implementation) took 0.758 seconds [fast_tanh(x) for x in d] (CPython C++ extension) took 0.076 seconds [fast_tanh2(x) for x in d] (PyBind11 C++ extension) took 0.204 seconds
В выходных данных вы можете увидеть, что расширение PyBind11 не такое быстрое, как расширение CPython, хотя оно все равно должно работать быстрее, чем прямая реализация на Python. Это различие в основном связано с тем, что мы использовали вызов METH_O , который не поддерживает несколько параметров, имен параметров или аргументов ключевых слов. PyBind11 формирует несколько более сложный код, чтобы предоставить вызывающим субъектам интерфейс, более похожий на Python. Но так как тестовый код вызывает функцию 500 000 раз, в результате эти дополнительные временные затраты могут сильно возрасти!
Чтобы сократить временные затраты, можно переместить цикл for в машинный код. Этот подход предполагает использование протокола итератора (или типа py::iterable из PyBind11 в качестве параметра функции) для обработки каждого элемента. Удаление повторяющихся переходов между Python и C++ является эффективным способом сокращения времени, затрачиваемого на обработку последовательности.
Устранение ошибок импорта
Если при попытке импорта модуля вы получаете сообщение ImportError , для разрешения этой проблемы можно использовать один из следующих способов.
- При сборке с помощью ссылки на проект убедитесь, что свойства проекта C++ соответствуют среде Python, активированной для проекта Python, особенно каталоги Include и Library.
- Убедитесь, что ваш выходной файл имеет имя superfastcode.pyd. Файл с любым другим именем или расширением не будет импортирован.
- Если вы установили модуль с помощью файла setup.py, убедитесь, что вы выполнили команду pip в среде Python, активированной для вашего проекта Python. При развертывании среды Python в обозревателе решений должна отображаться запись для superfastcode.
Отладка кода C++
Visual Studio поддерживает совместную отладку кода на Python и C++. В этом разделе вы пошагово выполните процесс с использованием проекта superfastcode. Этот процесс такой же, как для проекта superfastcode2.
-
В Обозревателе решений щелкните проект Python правой кнопкой мыши, выберите Свойства, откройте вкладку Отладка и выберите Отладка>Разрешить отладку машинного кода.
Совет При включении отладки машинного кода окно вывода Python может немедленно закрываться сразу после завершения программы без обычной паузы с сообщением Для продолжения нажмите любую клавишу. Решение: чтобы после включения отладки машинного кода принудительно приостановить выполнение программы, добавьте параметр -i в поле Запуск>Аргументы интерпретатора на вкладке Отладка. Этот аргумент переводит интерпретатор Python в интерактивный режим после выполнения кода, и для закрытия окна интерпретатора необходимо будет нажать клавиши CTRL+Z, а затем ВВОД. Кроме того, если вы не против изменения кода Python, можно добавить в конец программы операторы import os и os.system("pause") . Этот код дублирует исходный запрос с приостановкой.


Альтернативные подходы
Существуют различные способы для создания расширений Python, приведенные в таблице ниже. Способы CPython и PyBind11 , указанные в первых двух строках, рассматриваются в этой статье.
| Подход | Vintage | Представители |
|---|---|---|
| Модули расширений C/C++ для CPython | 1991 | Стандартная библиотека |
| PyBind11 (рекомендуется для C++) | 2015 | |
| Cython (рекомендуется для C) | 2007 | gevent, kivy |
| HPy | 2019 | |
| mypyc | 2017 | |
| ctypes | 2003 | oscrypto |
| cffi | 2013 | cryptography, pypy |
| SWIG | 1996 | crfsuite |
| Boost.Python | 2002 | |
| cppyy | 2017 |
См. также
Полный пример из этого руководства см. на GitHub по ссылке python-samples-vs-cpp-extension.
Настройка конфигураций отладки и выпуска в Visual Studio
Область применения:
Visual Studio Visual Studio для Mac
Visual Studio Code ![]()
Проекты Visual Studio имеют отдельные конфигурации выпуска и отладки для вашей программы. Производится построение отладочной версии для отладки и версии выпуска для окончательного выпуска программы.
Отладочная конфигурация программы компилируется с полной символической отладочной информацией и без оптимизации. Оптимизация усложняет отладку, поскольку усложняется связь между исходным кодом и сгенерированными инструкциями.
Конфигурация выпуска для программы полностью оптимизируется и не содержит символической отладочной информации. Для управляемого кода и кода C++ отладочная информация может быть создана в виде PDB-файлов в зависимости от используемых параметров компилятора. Создание PDB-файлов может оказаться полезным, если позднее возникнет необходимость в отладке версии выпуска.
Дополнительные сведения о конфигурациях сборки см. в статье Общие сведения о конфигурациях сборки.
Конфигурацию сборки можно изменить в меню Сборка на панели инструментов или на страницах свойств проекта. Страницы свойств проекта зависят от конкретного языка. Следующая процедура показывает, как изменить конфигурацию сборки из меню и на панели инструментов. Дополнительные сведения об изменении конфигурации сборки в проектах на разных языках см. в разделе См. также ниже.
Изменение конфигурации сборки
Для изменения конфигурации сборки сделайте следующее.

- На панели инструментов выберите либо Отладка, либо Выпуск из списка Конфигурации решения. or
- В меню Сборка щелкните Диспетчер конфигураций, а затем выберите Отладка или Выпуск.
Создание файлов символов (PDB) для сборки (C#, C++, Visual Basic, F#)
Можно выбрать создание файлов символов (PDB) и отладочные данные, которые необходимо включить. Для большинства типов проектов компилятор создает файлы символов по умолчанию для отладочных и окончательных сборок, в то время как другие параметры по умолчанию отличаются по типу проекта и версии Visual Studio.
Отладчик загружает PDB-файл для исполняемого файла, только если он точно соответствует PDB-файлу, который был создан при сборке исполняемого файла (то есть это должен быть либо оригинальный PDB-файл, либо его копия). Дополнительные сведения см. в статье Почему Visual Studio требует, чтобы файлы символов отладчика точно соответствовали двоичным файлам, с которыми они были собраны?
Каждый тип проекта может иметь свой способ установки этих параметров.
Создание файлов символов для проекта C# или ASP.NET Core (только для .NET Core и .NET 5 и более поздних версий)
Дополнительные сведения о параметрах проекта для конфигураций отладки C# см. в разделе Параметры проекта для конфигурации отладки C#. (Для проектов .NET в Visual Basic файлы символов настраиваются так же, как и на платформе .NET Framework.)

- В обозревателе решений щелкните правой кнопкой мыши проект и выберите пункт Свойства.
- В боковой панели выберите Сборка>Общие.
- В разделе Оптимизация кода выберите Отладка или Выпуск.
- В списке Отладочные символы выберите PDB-файл, текущая платформа, PDB-файл, переносимый или Внедренный. Переносимый формат разработан относительно недавно для кроссплатформенных приложений .NET Core. Дополнительные сведения о параметрах см. в статье Диалоговое окно "Дополнительные параметры сборки" (C#).
- Выполните сборку проекта. Компилятор создает файлы символов в той же папке, что и исполняемый файл или основной выходной файл.
Создание файлов символов для проекта C#, ASP.NET или Visual Basic (.NET Framework)
Дополнительные сведения о параметрах проекта для конфигурации отладки C# и Visual Basic см. в статьях Параметры проектов для конфигураций отладки C# и Параметры проекта для конфигурации отладки Visual Basic.

- В обозревателе решений щелкните правой кнопкой мыши проект и выберите пункт Свойства.
- В боковой области выберите Сборка (или Компилировать в Visual Basic).
- В списке Конфигурация в верхней части выберите Отладка или Выпуск.
- Нажмите кнопку Дополнительно (или Дополнительные параметры компиляции в Visual Basic).
- В списке Сведения об отладке (или Создать сведения об отладке в Visual Basic) выберите Полные, Только для PDB или Переносимые. Переносимый формат разработан относительно недавно для кроссплатформенных приложений .NET Core. Дополнительные сведения о параметрах см. в статье Диалоговое окно "Дополнительные параметры сборки" (C#).
- Выполните сборку проекта. Компилятор создает файлы символов в той же папке, что и исполняемый файл или основной выходной файл.
Создание файлов символов для проекта C++

- В обозревателе решений щелкните правой кнопкой мыши проект и выберите пункт Свойства.
- В списке Конфигурация выберите Отладка или Выпуск.
- В боковой области выберите Компоновщик > Отладка, а затем выберите параметры в разделе Создать сведения об отладке. В большинстве проектов C++ используется значение по умолчанию Создать отладочную информацию (/DEBUG). Дополнительные сведения о параметрах проекта для конфигурации отладки C++ см. в разделе Параметры проекта для конфигурации отладки C++.
- Настройте параметры для раздела Создание файлов базы данных программы. В большинстве проектов C++ значением по умолчанию является $(OutDir)$(TargetName).pdb , которое создает PDB-файлы в выходной папке.
- Выполните сборку проекта. Компилятор создает файлы символов в той же папке, что и исполняемый файл или основной выходной файл.
См. также
- Указание файлов символов (PDB) и исходных файлов в отладчике Visual Studio.
- Параметры отладчика и подготовка
- Параметры проекта для конфигурации отладки C++
- Параметры проекта для конфигурации отладки C#
- Параметры проекта для конфигурации отладки Visual Basic
- Практическое руководство. Создание и изменение конфигураций
