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ść.