Managed Extensions for C++またはManaged C++は、 C++の非推奨の言語拡張機能セットです。文法および構文の拡張、キーワード、属性などが含まれており、C++ の構文と言語を.NET Frameworkに導入できます。これらの拡張機能は、C++ コードをマネージドコードの形式で共通言語ランタイム (CLR) にターゲット設定し、ネイティブコードとの相互運用性を維持できるようにするために、Microsoftによって作成されました。
2004年、Managed C++拡張機能は大幅に改訂され、構文が明確化・簡素化され、マネージドジェネリックを含む機能が拡張されました。これらの新しい拡張機能はC++/CLIと命名され、 Microsoft Visual Studio 2005に含まれました。[ 1 ]そのため、 Managed C++という用語とそれが指す拡張機能は非推奨となり、新しい拡張機能に置き換えられました。
歴史
マイクロソフトはMicrosoft Visual C++ 2002 (MSVC++)でC++用マネージ拡張を導入しました。マイクロソフトは標準C++とC++用マネージ拡張の間の差異を最小限に抑えようと試みましたが、その結果、両者の根本的な違いは構文的に分かりにくくなっていました。MSVC++ 2003と2005では、マネージC++でのプログラム記述もサポートされていました。2004年、C++用マネージ拡張は廃止され、代わりにC++/CLIが導入されました。これは、マイクロソフトがC++を用いた共通言語基盤プログラミングをサポートするという2度目の試みでした。[ 2 ]
デザイン
マネージドとは、.NET仮想マシン内で実行される、または.NET仮想マシンによって管理されるマネージドコードを指します。.NET仮想マシンはサンドボックスとして機能し、バッファオーバーランチェックなどのランタイムチェックを強化することでセキュリティを強化します。また、マネージドC++で記述されたアプリケーションは、標準C++アプリケーションのようにネイティブCPU命令 に直接コンパイルされるのではなく、共通中間言語(CIL )にコンパイルされます。
マネージドC++コードは、 C#やVisual Basic .NETなど、CLRをターゲットとする他の言語と相互運用できるだけでなく、ガベージコレクションなどのCLRが提供する機能も利用できます。これは、マネージドC++が.NET言語群の中で独自の位置を占めていることを意味します。マネージドC++は、ネイティブC++だけでなく、C#やVB.NETなどの.NET言語とも直接通信できる唯一の言語です。他の.NET言語は、PInvokeまたはCOMを介してのみC++コードと通信できます。しかし、マネージドC++はマネージドC++と標準C++の両方のコンテキストで直接通信できるため、「ブリッジ」としてよく使用されます。
機能性
Managed 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 バイトコードに類似) 出力を生成するため、コンパイルされたモジュールとコンポーネント (アセンブリ) は、JScript .NET、C#、Visual Basic .NET、その他の .NET 用サード パーティ言語など、.NET Framework を対象とする別の言語で記述された他のプログラム コンポーネントで再利用できます。
- バージョン管理: 既存のクライアント側ソフトウェアとのバイナリ互換性を損なうことなく、新しいメソッドとデータ メンバーを既存のマネージ クラスに導入できます。
- バイナリ ヘッダー: 事前コンパイルされたメタデータの再利用を可能にします。MSIL にコンパイルされたすべての .exe、.dll、.obj、または .netmodule は、C++ ソース ファイルから参照できます。
- バッファオーバーフロー対策 - C++にガベージコレクションが導入されたことで、標準C++ではデータ型チェックが欠如しているために発生する一般的なバッファオーバーフローエラーが、マネージドC++では発生しにくくなりました。ガベージコレクターは、これらのエラーの発生頻度を(完全には減らないかもしれませんが)低減するのに役立ちます。
- .NET Framework基本クラス ライブラリ- マネージ C++ では、すべてのマネージ関数呼び出しと継承クラスが .NET Framework 基本クラス ライブラリ (BCL、FCL またはフレームワーク クラス ライブラリと呼ばれることもあります) から派生されるため、標準のアンマネージ コードよりも冗長性が低くなる可能性があります。その API は、TCP/IP ネットワーク機能、テキスト操作関数、データ アクセス (ODBC から SQL へ)、XML サービス (XSD から XSL へ)、GUI プログラミング (Windows フォーム)、メール サービス (SMTP)、暗号化 (X509 証明書および XML デジタル署名)、MSIL 生成 (基本的には MSIL で命令を生成)、ファイル I/O、CLR ガベージ コレクターの手動操作、および WMI コンソールを操作するための管理情報を提供します。
ネイティブコードに対する利点
- マネージドコードとアンマネージドコードを同じCLIアセンブリ内でシームレスに混在させることができます。これにより、プログラマーは、.NET Frameworkに移植するには完全に書き直す必要があるアンマネージドコードをそのまま保持できます。ただし、このハイブリッド規約を使用することで、いくつかの影響が生じます。
- マネージドC++は、アンマネージドコードを含み、他のすべての.NET言語とネイティブに通信できる唯一の言語です。そのため、マネージドC++は、.NET開発者と標準C++開発者を含む、異なる言語を使用するプログラマー間の相互運用性に非常に便利です。
アンマネージコードと比較したデメリット
- Managed C++ では、特に C++ コードが直接組み込まれ、同じアセンブリ内の Managed C++ コードと直接対話する場合に、コードの可読性を損なう可能性のある新しいキーワードと構文規則が多数導入されています。
- Managed C++ はC++/CLIに置き換えられ、 C++/CLIが標準化されたため廃止されました。
完全に管理されたコードと比較したデメリット
- マネージドC++は、同じ結果を生み出すプロジェクトに適用できる他の.NET言語と比べて、開発期間が若干長くなります。マネージドC++には値型(__value構造体と__valueクラス)と参照型(__gc構造体と__gcクラス)の両方があるため、ポインタの使用は必須の場合とそうでない場合があります。
- Managed C++ は、他のサードパーティ言語を含む他の .NET 言語よりも開発が難しいにもかかわらず、ASP.NET Web アプリケーションを完全にサポートしています。
- Managed C++ は、テンプレート(ネイティブ C++ との相互運用性のため)のみをサポートしていますが、ジェネリック(他のすべての .NET 言語との相互運用性のため)はサポートしていません。C ++/CLI は、テンプレート(コンパイル時)とジェネリック(実行時)の両方をサポートしています。
例
次の例は、標準 C++ と比較した Managed C++ の使用を示しています。
- (グローバル変更) CLR 経由で移植する既存の C++ には、次の内容を追加する必要があります。
// ゲロ.cpp// 新しい using ディレクティブ#using <mscorlib.dll>// 別の using namespace ディレクティブ。using namespace System ;int main () { Console :: WriteLine ( "Hello, world!" ); return 0 ; }新しいプリプロセッサディレクティブ
が必要です。さらに、ベースクラスライブラリでより多くの名前空間を使用するには、より多くのライブラリをインポートするために、より多くの#usingディレクティブが必要です。
#<System.Windows.Forms.dll> の使用
そして
名前空間System :: Windows :: Forms を使用します。
Windows フォームを使用します。
- CLR をターゲットとするコードをコンパイルするには、新しいコンパイラ オプションを導入する必要があります。
cl.exe hello.cpp /clr
/clr を使用すると、.NET Framework を参照するすべてのコードをCILとしてコンパイルできるようになります。
- 拡張キーワードを使用して、クラスをガベージ コレクションの対象として指定できます
__gc。
// ガベージコレクション.cpp#<mscorlib.dll> の使用__gcクラスGarbageCollected { int * i ; char * g ; float * j ; };int main () { while ( true ) { GarbageCollected ^ _gc = gcnew GarbageCollected (); } return 0 ; }上記のコードは、メモリリークを心配することなくコンパイルおよび実行できます。クラスはgcガベージコレクターによって管理されているため、delete演算子を呼び出す必要はありません。アンマネージドコードで同じことを実現するには、deleteキーワードが必要です。
// ガベージコレクションなし.cppクラスNotGarbageCollected { int * i ; char * g ; float * j ; };int main () { while ( true ) { NotGarbageCollected * g = new NotGarbageCollected (); gを削除します。} return 0 ; }注:
- __gc 指定されたクラスではコンストラクターを宣言できます。
- __gc 指定されたクラスではデストラクタを宣言できます。
- __gc 指定クラスは複数のクラスを継承できません。(これは CLR の制限です)
- __gc 指定クラスは、__gc 指定されていない別のクラスを継承できません。
- __gc 指定クラスは、__gc 指定されていない別のクラスに継承できません。
- __gc 指定クラスは任意の数の __gc インターフェースを実装できます。
- __gc 指定されたクラスは、アンマネージ インターフェイスを実装できません。
- __gc で指定されたクラスは、デフォルトでは自身のアセンブリの外部からは参照できません。
パブリック__gcクラスMyClass { // ... };__gc 指定クラスのアクセスを変更するには、public キーワードを使用します。
__gc 指定クラスは、delete キーワードを使用して手動で破棄できますが、__gc 指定クラスにユーザー定義のデストラクタがある場合に限られます。
- インターフェースは、その前に __gc 拡張キーワードを付けて宣言できます。例:
// MyInterface.cpp #<mscorlib.dll> を使用__gc __interface MyInterface { void init (); int common (); }単純な DLL ファイルを生成するには、上記のコードを /clr および /LD を使用してコンパイルする必要があります。
注:
- __gc __interface には、データ メンバー、静的メンバー、ネストされたクラス宣言、およびアクセス指定子を含めることはできません。
- __gc __interface は、別の __gc __interface インターフェースまたは System::Object からのみ継承できます。System::Object からの継承がデフォルトの動作です。
- __gc __interface には、宣言された関数プロトタイプの実装 (本体コード) を含めることはできません。
他の言語との比較
以下には、Managed C++ と概念が似ている他のよく知られたプログラミング言語との主な違いとプログラム標準が記載されています。
標準C++
デメリット
- ネイティブC++ コードは実行時に高速になる可能性があります。
- C++では、ターゲットシステムに関連するコンパイラとマネージドランタイム環境をインストールする必要がない。
- C++はジェネリックプログラミングをサポートしています。ただし、C++/CLIの最終リリースまでは、Managed C++プログラマーはジェネリックを使用するための回避策を講じる必要があります。
- C++はキーワード「const」とconstの正確性をサポートしています。JavaやC#と同様に、マネージドC++にはこの機能は含まれていません。代替案としては、マネージドクラスを不変にするか、パブリックインターフェースのsetアクセサを制限することが挙げられます。
- C++コードはCLRの制約に縛られません。例えば、CLRではクラスが他のクラスをプライベートまたはプロテクトで継承することは許可されていないため、以下のコードはコンパイラエラーになります。
パブリック__gcクラスFirst { int i ; };public __gc class Second : private First { int h ; i = h ; }; // エラーpublic __gc class Third : protected First { int h ; i = h ; }; // エラー- マネージド C++ __gc クラスは複数のクラスから継承できないため、次の例ではコンパイラ エラーが発生します。
__gc class First {}; __gc class Second {}; __gc class Third : public First , public Second {}; // エラーが発生します利点
- マネージド C++ は通常の C++ よりも高度なリフレクションをサポートしており、コードの機能や目的に応じて、通常ははるかに便利です。
- Managed C++ は、他のサードパーティ言語を含む、他のすべての .NET 対応言語と相互運用できます。
- マネージドC++はガベージコレクションされます。標準C++では、メモリ管理と割り当てはプログラマーの責任です。
ジャワ
違い
- Java コードを実行するには適切な仮想マシンが必要ですが、Managed C++ コードを実行するには .NET Framework の適切な実装が必要です。
デメリット
- Java はソースコードに関するドキュメントを提供しますが、Managed C++ は提供しません。
- Java には Java プログラマーが使用できる他の開発ツールが多数ありますが、Managed C++ はVisual Studio .NETでのみ使用できます。
利点
C#
違い
- C# は C++ と同様にポインターをサポートしていますが、この機能はデフォルトではオフになっています。
デメリット
- Javaと同様に、 C# はマネージコードを扱う際の構文がよりシンプルです。
- C# は、すべての構文と構造の規則が驚くほど似ているため、基本的に Managed C++ と同じ結果を実現できます。
- マネージド C++ は CLR に導入されているため厳密に型指定された言語ですが、同じコードベースにアンマネージ コンパイル コードが導入されるとエラーが発生しやすくなります。一方、C# は純粋な MSIL です。
利点
- C# では、低レベルでコンピュータ システムにアクセスするために、.NET Framework と提供されているクラス ライブラリを使用する必要があります。
- C または C++ から .NET Framework へのアプリケーションの移植は、Managed C++ を使用するとはるかに簡単になります。
- Microsoft Visual C++ .NET コンパイラは、Managed C++ を .NET Framework を対象にコンパイルし、結果のアセンブリでより成熟した命令セットを生成するため、パフォーマンスが向上します。
参照
参考文献
外部リンク