Zarządzane rozszerzenia dla C ++ - Managed Extensions for C++

Managed Extensions for C ++ lub Managed C ++ to obecnie przestarzały zestaw rozszerzeń językowych dla C ++ , w tym rozszerzenia gramatyczne i składniowe, słowa kluczowe i atrybuty, w celu przeniesienia składni i języka C ++ do platformy .NET Framework . Te rozszerzenia zostały stworzone przez firmę Microsoft, aby umożliwić C ++ kierowanie kodu do środowiska uruchomieniowego języka wspólnego (CLR) w postaci kodu zarządzanego , a także kontynuować współpracę z kodem natywnym.

W 2004 r. Rozszerzenia Managed C ++ zostały znacznie poprawione w celu wyjaśnienia i uproszczenia składni oraz rozszerzenia funkcjonalności o zarządzane typy ogólne . Te nowe rozszerzenia zostały oznaczone jako C ++ / CLI i zawarte w programie Microsoft Visual Studio 2005 . Termin Managed C ++ i rozszerzenia, do których się odnosi, są zatem przestarzałe i zastępowane przez nowe rozszerzenia.

Historia

Firma Microsoft wprowadziła zarządzane rozszerzenia dla języka C ++ w programie Microsoft Visual C ++ 2002 (MSVC ++). Firma Microsoft podjęła próbę zminimalizowania odchyleń między standardowym językiem C ++ a rozszerzeniami zarządzanymi w języku C ++, co spowodowało, że podstawowe różnice między nimi są zasłonięte składniowo. MSVC ++ 2003 i 2005 zapewniały również obsługę pisania programów w Managed C ++. W 2004 roku Managed Extensions for C ++ został uznany za przestarzały na rzecz C ++ / CLI , co jest drugą próbą firmy Microsoft w zakresie wspierania programowania infrastruktury języka wspólnego przy użyciu języka C ++.

Projekt

Managed odnosi się do kodu zarządzanego, który jest uruchamiany lub zarządzany przez maszynę wirtualną .NET , która działa jako piaskownica w celu zwiększenia bezpieczeństwa w postaci większej liczby kontroli w czasie wykonywania, takich jak sprawdzanie przepełnienia buforu. Ponadto aplikacje napisane w Managed C ++ kompilują się do CIL - Common Intermediate Language - a nie bezpośrednio do natywnych instrukcji procesora, jak robią to standardowe aplikacje C ++.

Zarządzany kod C ++ może współdziałać z dowolnym innym językiem również przeznaczonym dla środowiska CLR, takim jak C # i Visual Basic .NET, a także korzystać z funkcji zapewnianych przez środowisko CLR, takich jak wyrzucanie elementów bezużytecznych . Oznacza to, że Managed C ++ zajmuje wyjątkowe miejsce w galerii języków .NET. Jest to jedyny język, który może komunikować się bezpośrednio z językami .NET (takimi jak C #, VB.NET), a także z natywnym C ++. Inne języki .NET mogą komunikować się z kodem C ++ tylko za pośrednictwem PInvoke lub COM . Ale ponieważ zarządzany C ++ może komunikować się bezpośrednio zarówno w zarządzanym, jak i standardowym kontekście C ++, jest często używany jako „pomost”.

Funkcjonalność

Programy napisane w Managed C ++ zapewniają dodatkowe funkcje .NET Framework i CLR . Najbardziej godnym uwagi z nich jest czyszczenie pamięci, które zwalnia programistę z ręcznego zarządzania pamięcią. Moduł odśmiecania pamięci (GC) jest obsługiwany przez środowisko CLR. Zarządzanie pamięcią jest wykonywane dość szybko, ale w przypadku aplikacji o bardziej krytycznym znaczeniu dla wydajności preferowaną opcją jest prawdopodobnie kod natywny, niezarządzany.

Managed C ++ jest nastawiony na programowanie obiektowe. Główną różnicą między standardowym C ++ a zarządzanym C ++ jest to, że dziedziczenie wielokrotne nie jest obsługiwane, a klasa zarządzana w ramach modułu wyrzucania elementów bezużytecznych środowiska CLR nie może dziedziczyć więcej niż jednej klasy. Dzieje się tak z powodu ograniczenia CLR.

Kluczowe cechy:

  • Rozszerzalne metadane: informacje dostarczane w celu opisania struktury i typów zarządzanego składnika. Można go rozszerzyć i ponownie wykorzystać do tworzenia komponentów oprogramowania. Jest często używany w językach C # i Visual Basic .NET
  • Wyrzucanie elementów bezużytecznych: środowisko CLR jest w pełni zarządzane przez moduł odśmiecania pamięci w celu zautomatyzowania zarządzania pamięcią przez samo środowisko CLR, tj. Operator usuwania nie musi być wywoływany w zarządzanym kodzie C ++.
  • Interoperacyjność z językami .NET: kod przeznaczony dla platformy .NET Framework generuje dane wyjściowe w języku Microsoft Intermediate Language (MSIL, podobny do kodu bajtowego Java), a zatem skompilowane moduły i komponenty (raczej zestawy) mogą być ponownie wykorzystane przez inne komponenty programu napisane w innym języku, przeznaczone .NET Framework, na przykład JScript .NET, C #, Visual Basic .NET i inne języki innych firm dla .NET.
  • Przechowywanie wersji: nowe metody i składowe danych można wprowadzać do istniejących klas zarządzanych bez naruszania zgodności binarnej z istniejącym oprogramowaniem po stronie klienta.
  • Nagłówki binarne: umożliwia ponowne użycie wstępnie skompilowanych metadanych; do dowolnego modułu .exe, .dll, .obj lub .netmodule skompilowanego do MSIL można się odwoływać z pliku źródłowego C ++.
  • Ochrona przed przepełnieniem bufora - wraz z wprowadzeniem czyszczenia pamięci do C ++, Managed C ++ jest mniej podatny na typowe błędy przepełnienia bufora spowodowane brakiem sprawdzania typu danych w standardowym C ++. Moduł odśmiecania pamięci pomaga zmniejszyć (chociaż nie całkowicie) częstotliwość tych błędów.
  • Biblioteka klas bazowych platformy .NET Framework - zarządzany język C ++ może być również mniej rozwlekły niż standardowy kod niezarządzany, ponieważ wszystkie wywołania funkcji zarządzanych i klasy dziedziczone pochodzą z biblioteki klas podstawowych platformy .NET Framework (BCL, czasami nazywanej FCL lub Framework Class Library), którego API zapewnia możliwości sieciowe TCP / IP, funkcje manipulacji tekstami, dostęp do danych (od ODBC do SQL), usługi XML (od XSD do XSL), programowanie GUI (Windows Forms), usługi pocztowe (SMTP), kryptografię ( Certyfikaty X509 i podpisy cyfrowe XML), generowanie MSIL (zasadniczo emitowanie instrukcji w MSIL), we / wy pliku, ręczne manipulowanie modułem odśmiecania pamięci CLR i informacje o zarządzaniu w celu manipulowania konsolą WMI.

Zalety w stosunku do kodu natywnego

  • Kod zarządzany i niezarządzany można bezproblemowo mieszać razem w tym samym zestawie CLI . Pozwala to programiście na zachowanie niezarządzanego kodu, którego nie można przenieść do .NET Framework bez całkowitego przepisania go. Istnieją jednak pewne konsekwencje stosowania tej konwencji hybrydowej.
  • Zarządzany C ++ to jedyny język, który może zawierać niezarządzany kod i natywnie komunikować się ze wszystkimi innymi językami .NET. Zarządzany C ++ jest więc bardzo wygodny dla współdziałania między programistami, którzy używają różnych języków, w tym tych z teatru .NET i tymi, którzy używają standardowego C ++.

Wady w porównaniu z niezarządzanym kodem

  • Managed C ++ wprowadza wiele nowych słów kluczowych i konwencji składniowych, które mogą osłabić czytelność kodu, zwłaszcza jeśli kod C ++ jest dołączony bezpośrednio i współdziała bezpośrednio z kodem Managed C ++ w tym samym zestawie.
  • Zarządzany C ++ jest zastępowany przez C ++ / CLI i dlatego jest przestarzały, ponieważ C ++ / CLI został znormalizowany.

Wady w porównaniu do w pełni zarządzanego kodu

  • Zarządzany C ++ wymaga nieco dłuższego czasu programowania niż inne języki .NET, które można zastosować w projektach, które nadal dają takie same wyniki. Użycie wskaźników może być wymagane lub nie, ponieważ zarządzany C ++ ma zarówno typy wartości (struktura __value i klasa __value), jak i typy odwołań (struktura __gc i klasa __gc).
  • Managed C ++ w pełni obsługuje aplikacje internetowe ASP.NET , mimo że programowanie jest trudniejsze niż w przypadku innych języków .NET, w tym niektórych języków innych firm.
  • Zarządzany C ++ obejmuje tylko obsługę szablonów (dla współdziałania z natywnym C ++), ale nie obsługuje typów ogólnych (dla współdziałania ze wszystkimi innymi językami .NET). C ++ / CLI obsługuje zarówno szablony (w czasie kompilacji), jak i typy ogólne (w czasie wykonywania).

Przykłady

Poniższe przykłady przedstawiają użycie Managed C ++ w porównaniu ze standardowym C ++:

  • (Zmiana globalna) Istniejący język C ++, który ma zostać przeniesiony przez środowisko CLR, należy uzupełnić o następujące elementy:
//hello.cpp

//new using directive
#using <mscorlib.dll>

//another using namespace directive.
using namespace System;

int main()
{
  Console::WriteLine("Hello, world!");
  return 0;
}

Nowa dyrektywa preprocesora

#using <mscorlib.dll>

jest wymagane. Oprócz tego potrzeba więcej dyrektyw #using, aby zaimportować więcej bibliotek, aby używać większej liczby przestrzeni nazw w bibliotece klas podstawowych, takich jak

#using <System.Windows.Forms.dll>

i

using namespace System::Windows::Forms;

używać Windows Forms.

  • Aby skompilować kod pod kątem środowiska CLR, należy wprowadzić nową opcję kompilatora.
   cl.exe hello.cpp /clr

/ clr umożliwia kompilację dowolnego kodu odwołującego się do .NET Framework jako CIL .

  • Klasę można wyznaczyć do zbierania elementów bezużytecznych za pomocą __gc słowa kluczowego rozszerzenia.
//gc.cpp

#using <mscorlib.dll>

 __gc class gc
{
  int* i;
  char* g;
  float* j;
};

int main()
{
  while (true)
  {
    gc^ _gc = gcnew gc();
  }
  return 0;
}

Poprzedni kod można skompilować i wykonać bez obawy o wycieki pamięci . Ponieważ klasa gc jest zarządzana z poziomu modułu odśmiecania pamięci, nie ma potrzeby dzwonienia do delete operatora. Aby osiągnąć to samo z niezarządzanym kodem, delete wymagane jest słowo kluczowe:

//nogc.cpp

class gc
{
  int* i;
  char* g;
  float* j;
};

int main()
{
  while (true)
  {
    gc* _gc = new gc();
    delete _gc;
  }
  return 0;
}

Uwagi:

  • Wyznaczona klasa __gc może mieć zadeklarowany konstruktor.
  • Klasa wyznaczona __gc może mieć zadeklarowany destruktor.
  • Klasa wyznaczona przez __gc nie może dziedziczyć więcej niż jednej klasy. (To jest ograniczenie CLR)
  • Klasa wyznaczona przez __gc nie może dziedziczyć innej klasy, która nie została wyznaczona przez __gc.
  • Klasa wyznaczona przez __gc nie może być dziedziczona przez inną klasę, która nie została wyznaczona przez __gc.
  • Wyznaczona klasa __gc może implementować dowolną liczbę interfejsów __gc.
  • Wyznaczona klasa __gc nie może zaimplementować niezarządzanego interfejsu.
  • Wyznaczona klasa __gc nie jest domyślnie widoczna poza własnym zestawem. Posługiwać się
public __gc class hey  { };

słowo kluczowe public do modyfikowania dostępu wyznaczonej klasy __gc.

Wyznaczoną klasę __gc można zniszczyć ręcznie za pomocą słowa kluczowego delete, ale tylko wtedy, gdy wyznaczona klasa __gc ma destruktor zdefiniowany przez użytkownika.

  • Interfejs można zadeklarować za pomocą poprzedzającego go słowa kluczowego rozszerzenia __gc. Jak na przykład:
//interface.cpp
#using <mscorlib.dll>

__gc __interface ClassBase
{
  void Init();
  int Common();
}

Poprzedni kod musi zostać skompilowany z / clr i / LD, aby utworzyć prosty plik DLL.

Uwagi:

  • __Gc __interface nie może zawierać żadnych elementów członkowskich danych, statycznych elementów członkowskich, zagnieżdżonych deklaracji klas ani żadnych specyfikatorów dostępu.
  • __Gc __interface może dziedziczyć tylko z innego interfejsu __gc __interface lub System :: Object. Dziedziczenie z System :: Object jest zachowaniem domyślnym.
  • Interfejs __gc __ nie może zawierać żadnej implementacji (kodu treści) zadeklarowanych prototypów funkcji.

Porównanie z innymi językami

Poniżej przedstawiono główne punkty i standardy programistyczne, które różnią się między Managed C ++ a innymi dobrze znanymi językami programowania o podobnej koncepcji.

Standardowy C ++

Niedogodności

  • natywny kod C ++ może być szybszy w czasie wykonywania.
  • C ++ nie wymaga instalacji skojarzonego kompilatora i zarządzanego środowiska wykonawczego w systemie docelowym
  • C ++ obsługuje programowanie ogólne . Jednak aż do ostatecznego wydania C ++ / CLI programiści Managed C ++ muszą wrócić do obejścia dla używania typów ogólnych.
  • C ++ obsługuje słowo kluczowe „const” i poprawność const . Zarządzany C ++, podobnie jak Java i C #, nie zawiera tej funkcji. Alternatywą jest uczynienie klasy zarządzanej niezmienną lub ograniczenie dostępu do zestawu w interfejsach publicznych.
  • Kod C ++ nie jest ograniczony przez ograniczenia środowiska CLR. Na przykład środowisko CLR nie zezwala klasom na dziedziczenie innych klas prywatnie ani chronionych, dlatego poniższy błąd spowoduje błąd kompilatora:
public __gc class one { int i; };
public __gc class two: private one { int h; i = h; }; // error
public __gc class three: protected one { int h; i=h;}; // error
  • Zarządzane klasy C ++ __gc nie mogą dziedziczyć z więcej niż jednej klasy, ponieważ poniższe spowoduje błąd kompilatora:
__gc class a {};
__gc class b {};
__gc class c: public a, public b {}; //will produce an error

Zalety

  • Zarządzany C ++ obsługuje większy stopień refleksji niż zwykły C ++, co jest ogólnie dużo wygodniejsze w zależności od funkcji kodu lub tego, do czego jest przeznaczony.
  • Zarządzany C ++ może współdziałać ze wszystkimi innymi językami obsługującymi .NET, w tym językami innych firm.
  • Zarządzany C ++ jest odśmiecany. W standardowym C ++ za zarządzanie i alokację pamięci odpowiada programista.

Jawa

Różnice

  • Uruchamianie kodu Java wymaga odpowiedniej maszyny wirtualnej, podczas gdy kod Managed C ++ wymaga odpowiedniej implementacji platformy .NET Framework.

Niedogodności

  • Java udostępnia dokumentację dotyczącą kodu źródłowego, podczas gdy Managed C ++ nie.
  • Java ma wiele innych narzędzi programistycznych dostępnych dla programistów Java, podczas gdy Managed C ++ jest dostępne tylko w Visual Studio .NET .

Zalety

  • Zarządzany C ++ może uzyskać dostęp do systemu komputerowego poprzez interfejs niskiego poziomu o wiele łatwiej niż Java. Programiści Java muszą używać JNI (Java Native Interface), aby korzystać z usług niskiego poziomu systemu operacyjnego hosta.

DO#

Różnice

  • Chociaż C # obsługuje wskaźniki, podobnie jak w C ++, ta funkcja jest domyślnie wyłączona.

Niedogodności

  • Podobnie jak Java , C # jest prostszy składniowo w przypadku kodu zarządzanego.
  • C # może osiągnąć zasadniczo ten sam wynik, co Managed C ++, ponieważ wszystkie konwencje składniowe i strukturalne pozostają uderzająco podobne.
  • Zarządzany C ++, chociaż jest to język silnie typizowany ze względu na jego wprowadzenie do środowiska CLR, może być podatny na błędy, jeśli niezarządzany skompilowany kod zostanie wprowadzony w tej samej bazie kodu, podczas gdy C # jest czystym MSIL.

Zalety

  • C # musi używać .NET Framework i dostarczonych bibliotek klas, aby uzyskać dostęp do systemu komputerowego na niskim poziomie.
  • Przenoszenie aplikacji na platformę .NET Framework z C lub C ++ jest znacznie łatwiejsze przy użyciu Managed C ++.
  • Kompilator Microsoft Visual C ++ .NET, który kompiluje Managed C ++ pod kątem platformy .NET Framework, tworzy znacznie bardziej dojrzały zestaw instrukcji w wynikowym asemblacji, poprawiając w ten sposób wydajność.

Zobacz też

Bibliografia

Zewnętrzne linki