Managed Extensions for C++ или Managed C++ — устаревший набор языковых расширений для C++ , включая грамматические и синтаксические расширения, ключевые слова и атрибуты, для переноса синтаксиса и языка C++ в .NET Framework . Эти расширения были созданы корпорацией Microsoft, чтобы код C++ можно было нацеливать на Common Language Runtime (CLR) в форме управляемого кода , а также продолжать взаимодействовать с машинным кодом.
В 2004 году расширения Managed C++ были существенно пересмотрены для уточнения и упрощения синтаксиса и расширения функциональности для включения управляемых дженериков . Эти новые расширения были обозначены как C++/CLI и включены в Microsoft Visual Studio 2005. [ 1] Термин Managed C++ и расширения, на которые он ссылается, таким образом, устарели и заменены новыми расширениями.
История
Microsoft представила Managed Extensions для C++ в Microsoft Visual C++ 2002 (MSVC++). Microsoft попыталась минимизировать отклонения между стандартным C++ и Managed Extensions для C++, в результате чего основные различия между ними были синтаксически скрыты. MSVC++ 2003 и 2005 также обеспечивали поддержку написания программ на Managed C++. В 2004 году Managed Extensions для C++ был упразднен в пользу C++/CLI , второй попытки Microsoft поддержать программирование для Common Language Infrastructure с использованием C++. [2]
Дизайн
Управляемый относится к управляемому коду , который выполняется или управляется виртуальной машиной .NET , которая функционирует как песочница для повышения безопасности в виде большего количества проверок во время выполнения, таких как проверки переполнения буфера. Кроме того, приложения, написанные на управляемом C++, компилируются в CIL — Common Intermediate Language — а не напрямую в собственные инструкции ЦП , как это делают стандартные приложения C++.
Управляемый код C++ может взаимодействовать с любым другим языком, также предназначенным для CLR , таким как C# и Visual Basic .NET , а также использовать функции, предоставляемые CLR, такие как сборка мусора . Это означает, что управляемый C++ занимает уникальное положение в галерее языков .NET. Это единственный язык, который может напрямую взаимодействовать с языками .NET (такими как C#, VB.NET), а также с собственным C++. Другие языки .NET могут взаимодействовать с кодом C++ только через PInvoke или COM . Но поскольку управляемый C++ может напрямую взаимодействовать как в управляемом, так и в стандартном контексте C++, его часто используют в качестве «моста».
Функциональность
Программы, написанные на управляемом C++, предоставляют дополнительную функциональность .NET Framework и CLR . Наиболее примечательной из них является сборка мусора , которая освобождает программиста от ручного управления памятью. Сборщик мусора (GC) обрабатывается CLR. Управление памятью выполняется довольно быстро, но для более критичных к производительности приложений, скорее всего, предпочтительным вариантом будет собственный, неуправляемый код.
Managed C++ ориентирован на объектно-ориентированное программирование. Главное отличие стандартного C++ от Managed C++ заключается в том, что множественное наследование не поддерживается, а класс, управляемый сборщиком мусора CLR, не может наследовать более одного класса. Это связано с ограничением CLR.
Основные характеристики:
- Расширяемые метаданные: информация, предоставляемая для описания структуры и типов управляемого компонента. Она может быть расширена и повторно использована для создания программных компонентов. Она активно используется в C# и Visual Basic .NET
- Сборка мусора: CLR полностью управляется сборщиком мусора для управления памятью, автоматизированного самой CLR, т. е. оператор удаления не нужно вызывать в управляемом коде C++.
- Взаимодействие с языками .NET: код, предназначенный для .NET Framework, создает вывод на языке Microsoft Intermediate Language (MSIL, аналогичный байт-коду Java), и, таким образом, скомпилированные модули и компоненты (скорее сборки) могут повторно использоваться другими компонентами программы, написанными на другом языке, предназначенном для .NET Framework, например, JScript .NET, C#, Visual Basic .NET и других сторонних языках для .NET.
- Управление версиями: новые методы и элементы данных могут быть введены в существующие управляемые классы без нарушения двоичной совместимости с существующим клиентским программным обеспечением.
- Двоичные заголовки: позволяют повторно использовать предварительно скомпилированные метаданные; на любой .exe, .dll, .obj или .netmodule, скомпилированный в MSIL, можно ссылаться из исходного файла C++.
- Защита от переполнения буфера - с введением сборки мусора в C++, управляемый C++ менее подвержен распространенным ошибкам переполнения буфера , вызванным отсутствием проверки типов данных в стандартном C++. Сборщик мусора помогает снизить (хотя и не полностью) частоту этих ошибок.
- Библиотека базовых классов .NET Framework — управляемый C++ также может быть менее многословным, чем стандартный неуправляемый код, поскольку все управляемые вызовы функций и унаследованные классы получены из библиотеки базовых классов .NET Framework (BCL, иногда называемой FCL или библиотекой классов Framework), API которой предоставляет сетевые возможности TCP/IP, функции текстовой обработки, доступ к данным (от ODBC до SQL), службы XML (от XSD до XSL), программирование графического интерфейса пользователя (Windows Forms), почтовые службы (SMTP), криптографию (сертификаты X509 и цифровые подписи XML), генерацию MSIL (по сути, выдачу инструкций в MSIL), файловый ввод-вывод, ручное управление сборщиком мусора CLR и информацию управления для управления консолью WMI.
Преимущества перед собственным кодом
- Управляемый и неуправляемый код можно легко смешивать в одной сборке CLI . Это позволяет программисту сохранять неуправляемый код, который нельзя перенести в .NET Framework без его полной переписывания. Однако существуют некоторые последствия использования этого гибридного соглашения.
- Managed C++ — единственный язык, который может содержать неуправляемый код и изначально взаимодействовать со всеми другими языками .NET. Managed C++, таким образом, очень удобен для взаимодействия между программистами, использующими разные языки, включая тех, кто работает в театре .NET, и тех, кто использует стандартный C++.
Недостатки по сравнению с неуправляемым кодом
- Управляемый C++ вводит множество новых ключевых слов и синтаксических соглашений, которые могут ухудшить читаемость кода, особенно если код C++ включен напрямую и напрямую взаимодействует с управляемым кодом C++ в той же сборке.
- Управляемый C++ заменен C++/CLI и, таким образом, устарел, поскольку C++/CLI был стандартизирован.
Недостатки по сравнению с полностью управляемым кодом
- Управляемый C++ требует немного больше времени на разработку, чем другие языки .NET, которые можно применять к проектам, которые все равно дают те же результаты. Использование указателей может быть или не быть обязательным, поскольку управляемый C++ имеет как типы значений (структура __value и класс __value), так и ссылочные типы (структура __gc и класс __gc).
- Управляемый C++ полностью поддерживает веб-приложения ASP.NET , хотя разработка сложнее, чем на других языках .NET, включая некоторые другие сторонние языки.
- Управляемый C++ включает только поддержку шаблонов (для взаимодействия с собственным C++), но не поддерживает дженерики (для взаимодействия со всеми другими языками .NET). C++/CLI поддерживает как шаблоны (во время компиляции), так и дженерики (во время выполнения).
Примеры
Следующие примеры иллюстрируют использование управляемого C++ по сравнению со стандартным C++:
- (Глобальное изменение) Существующий код C++, который необходимо перенести через CLR, должен быть дополнен следующим:
//привет.cpp//новая директива using #using <mscorlib.dll>//еще одна директива using namespace. using namespace System ; int main () { Console :: WriteLine ( "Привет, мир!" ); return 0 ; }
Новая директива препроцессора
#использование <mscorlib.dll>
требуется. В дополнение к этому, требуются дополнительные директивы #using для импорта большего количества библиотек для использования большего количества пространств имен в библиотеке базовых классов, например
#использование <System.Windows.Forms.dll>
и
использование пространства имен System :: Windows :: Forms ;
использовать Windows Forms.
- Чтобы скомпилировать код для CLR, необходимо ввести новую опцию компилятора.
cl.exe hello.cpp /clr
/clr позволяет компилировать любой код, ссылающийся на .NET Framework, как CIL .
- Класс можно назначить для сбора мусора с помощью
__gc
ключевого слова extension.
//gc.cpp#использование <mscorlib.dll> __gc класс gc { int * i ; char * g ; float * j ; }; int main () { while ( true ) { gc ^ _gc = gcnew gc (); } return 0 ; }
Предыдущий код можно скомпилировать и выполнить, не опасаясь утечек памяти . Поскольку класс gc
управляется сборщиком мусора, нет необходимости вызывать delete
оператор. Чтобы добиться того же самого с неуправляемым кодом, delete
требуется ключевое слово:
//nogc.cppкласс gc { int * i ; char * g ; float * j ; }; int main () { while ( true ) { gc * _gc = new gc (); delete _gc ; } return 0 ; }
Примечания:
- Класс, обозначенный __gc, может иметь объявленный конструктор.
- Класс, обозначенный __gc, может иметь объявленный деструктор.
- Класс, назначенный __gc, не может наследовать более одного класса. (Это ограничение CLR)
- Класс, обозначенный __gc, не может наследовать другой класс, не обозначенный __gc.
- Класс, обозначенный __gc, не может быть унаследован другим классом, не обозначенным __gc.
- Класс, обозначенный __gc, может реализовывать любое количество интерфейсов __gc.
- Класс, назначенный __gc, не может реализовать неуправляемый интерфейс.
- Класс, назначенный __gc, по умолчанию не виден за пределами его собственной сборки.
public __gc class эй { };
ключевое слово public для изменения доступа к назначенному классу __gc.
Класс, обозначенный __gc, можно уничтожить вручную с помощью ключевого слова delete, но только в том случае, если у класса, обозначенного __gc, есть определенный пользователем деструктор.
- Интерфейс может быть объявлен с ключевым словом расширения __gc, предшествующим ему. Например:
//interface.cpp #используя <mscorlib.dll>__gc __interface ClassBase { void Init (); int Common (); }
Для создания простого DLL-файла предыдущий код необходимо скомпилировать с использованием /clr и /LD.
Примечания:
- Интерфейс __gc __interface не может содержать никаких членов данных, статических членов, вложенных объявлений классов и спецификаторов доступа.
- Интерфейс __gc __interface может наследоваться только от другого интерфейса __gc __interface или System::Object. Наследование от System::Object является поведением по умолчанию.
- Интерфейс __gc __interface не может содержать никакой реализации (кода тела) своих объявленных прототипов функций.
Сравнение с другими языками
Ниже приведены основные положения и стандарты программирования, которые различаются между управляемым C++ и другими известными языками программирования, имеющими схожую концепцию.
Стандартный С++
Недостатки
- Собственный код C++ может работать быстрее во время выполнения.
- C++ не требует установки соответствующего компилятора и управляемой среды выполнения на целевой системе.
- C++ поддерживает обобщенное программирование . Однако до окончательного выпуска C++/CLI программисты управляемого C++ должны вернуться к обходным путям использования обобщений.
- C++ поддерживает ключевое слово "const" и const correctness . Управляемый C++, как и Java и C#, не содержит этой возможности. Альтернативой является сделать управляемый класс неизменяемым или ограничить наборы методов доступа на открытых интерфейсах.
- Код C++ не ограничен ограничениями CLR. Например, CLR не позволяет классам наследовать другие классы ни в частном порядке, ни защищенно, поэтому следующее приведет к ошибке компиляции:
public __gc class one { int i ; }; public __gc class two : private one { int h ; i = h ; }; // ошибка public __gc class three : protected one { int h ; i = h ;}; // ошибка
- Управляемые классы C++ __gc не могут наследовать более чем от одного класса, поэтому следующее приведет к ошибке компиляции:
__gc class a {}; __gc class b {}; __gc class c : public a , public b {}; //выдаст ошибку
Преимущества
- Управляемый C++ поддерживает большую степень рефлексии , чем обычный C++, что, как правило, гораздо удобнее в зависимости от функции кода или от того, для чего он предназначен.
- Управляемый C++ может взаимодействовать со всеми другими языками, совместимыми с .NET, включая сторонние языки.
- Managed C++ — сборщик мусора. В стандартном C++ управление памятью и ее распределение — это ответственность программиста.
Ява
Различия
- Для запуска кода Java требуется соответствующая виртуальная машина, тогда как для запуска управляемого кода C++ требуется соответствующая реализация .NET Framework.
Недостатки
- Java предоставляет документацию по исходному коду, тогда как Managed C++ — нет.
- Java имеет множество других инструментов разработки, доступных Java-программистам, в то время как Managed C++ доступен только в Visual Studio .NET .
Преимущества
- Управляемый C++ может получить доступ к компьютерной системе на низкоуровневом интерфейсе гораздо проще, чем Java. Программисты Java должны использовать JNI (Java Native Interface) для использования низкоуровневых служб операционной системы хоста.
С#
Различия
- Хотя C# поддерживает указатели так же, как и C++, эта функция по умолчанию отключена.
Недостатки
- Как и Java , C# синтаксически проще при работе с управляемым кодом.
- C# позволяет достичь в принципе того же результата, что и управляемый C++, поскольку все синтаксические и структурные соглашения остаются поразительно схожими.
- Управляемый C++, хотя и является строго типизированным языком из-за его внедрения в CLR, может быть подвержен ошибкам, если в ту же кодовую базу вводится неуправляемый скомпилированный код, в то время как C# — это чистый MSIL.
Преимущества
- C# должен использовать .NET Framework и предоставленные библиотеки классов для доступа к компьютерной системе на низком уровне.
- Перенос приложений на .NET Framework с C или C++ гораздо проще осуществлять с помощью управляемого C++.
- Компилятор Microsoft Visual C++ .NET, который компилирует управляемый C++ для целевой платформы .NET Framework, создает в своей результирующей сборке гораздо более продуманный набор инструкций, тем самым повышая производительность.
Смотрите также
Ссылки
- ^ "Руководство по переводу: перемещение программ из управляемых расширений для C++ в C++/CLI". Microsoft . Август 2004. Получено 11 ноября 2009 г.
- ^ Sutter, Herb. "A Design Rationale for C/C++" (PDF) . стр. 6. Архивировано (PDF) из оригинала 2017-08-30 . Получено 2018-06-12 .
Внешние ссылки
- Управляемые расширения для C++ (на MSDN)
- Статья: C++ / CLI — как использовать управляемую библиотеку DLL C++, если не установлен Microsoft Visual C++ Redistributable?