C++/CLI

C ++ / CLI(共通言語インフラストラクチャ用に変更されたC ++ )は、Microsoftによって作成された言語仕様であり、C ++のManagedExtensionsに取って代わります。これは完全なリビジョンであり、現在は非推奨のマネージC ++構文を簡素化し、C#などのMicrosoft.NET言語との相互運用性を提供します。C ++ / CLIは、EcmaによってECMA-372として標準化されました。現在、Expressエディションを含め、Visual Studio 2005、2008、2010、2012、2013、2015、2017、および2019で使用できます。
C ++ / CLI
パラダイム
構造化された、命令型の、オブジェクト指向
家族 C によって設計された
マイクロソフト
開発者
マイクロソフト
初登場
2005 ; 16年前 (2005)
安定したリリース
標準ECMA-372 / 2005年12月 ; 15年前  (2005-12)
プラットホーム
共通言語基盤
ウェブサイト
www .ecma-international .org / publications / standard / Ecma-372 .htm
に影響を受けた
C ++、C ++のマネージ拡張、C#
内容
1 構文の変更
1.1 ハンドル 1.2 参照の追跡 1.3 ファイナライザーと自動変数
2 演算子のオーバーロード
3 C ++ / C#の相互運用性
4 C ++ / CX
5 参考文献
6 外部リンク
構文の変更
C ++ / CLIは、(例えば、キーワードの新しいセットを持つ)、代わりにC ++スーパーセット指向の独自の言語と考えるべきであるマネージドC ++(非標準のキーワードのようなスタイルました(MC ++)__gcまたは__value)。このため、特にあいまいな識別子の削除と.NET固有の機能の追加に関連して、いくつかの主要な構文上の変更が
MC ++の演算子の複数のバージョンなど、多くの競合する構文が分割されました。C++ / CLIでは、.NET参照型がnewキーワードで作成されます(つまり、ガベージコレクションされたnew())。また、C ++ / CLIは、.NETからジェネリックスの概念を導入しました(最も一般的な目的では、標準のC ++テンプレートに似ていますが、実装がまったく異なります)。new()gcnew
ハンドル
MC ++には、2つの異なるタイプのポインターがありました。__nogcポインターは通常のC ++ポインターでしたが、__gcポインターは.NET参照タイプで機能していました。ただし、C ++ / CLIでは、ポインターのタイプは通常のC ++ポインターのみですが、.NET参照タイプには、(ではなく)新しい構文を使用した「ハンドル」を介してアクセスします。この新しい構成は、マネージドコードと標準C ++コードが混在している場合に特に役立ちます。どのオブジェクトが.NET自動ガベージコレクションの下にあり、プログラマーが明示的に破棄することを覚えておく必要があるオブジェクトを明確にします。ClassName^ClassName*
参照の追跡
トラッキング基準C ++ / CLIでは、渡されたバイ参照変数のハンドルです。概念的には*&、標準のC ++で” “(ポインターへの参照)を使用するのと似ており、(関数宣言で)refC#の型に適用される” “キーワード、またはVisual Basic.NETの” ByRef”に対応します。C ++ / CLIは、「^%」構文を使用して、ハンドルへの追跡参照を示します。
次のコードは、追跡参照の使用例を示しています。追跡参照を通常のハンドル変数に置き換えると、参照ではなく値によって渡されるため、配列内の文字列ハンドルのコピーのみが設定されるため、結果の文字列配列には初​​期化されていない10個の文字列ハンドルが残ります。
int main (){ array < String ^> ^ arr = gcnew array < String ^> (10 ); int i = 0 ; for each (String ^% s in arr ) {
s = i ++ 。ToString (); } 0を返す; }
これはC#では違法であり、foreachループが参照によって値を渡すことを許可しないことに注意してしたがって、回避策が必要になります。
ファイナライザーと自動変数
C ++ / CLIのもう1つの変更点は、ガベージコレクションルーチンの一部として実行される特殊なタイプの非決定論的デストラクタであるファイナライザ構文の導入です。C ++デストラクタ構文は、管理対象オブジェクトにも存在し、決定論的破壊の「従来の」C ++セマンティクス(つまり、を使用してユーザーコードで呼び出すことができるデストラクタ)をより適切に反映します。!ClassName()~ClassName()delete
生の.NETパラダイムでは、非決定論的破壊モデルFinalizeはルートObjectクラスの保護されたメソッドをオーバーライドしますが、決定論的モデルはIDisposable インターフェイスメソッドDispose(C ++ / CLIコンパイラがデストラクタを変換します)を介して実装されます。DisposeメソッドをオーバーライドするC#またはVB.NETコードのオブジェクトは、C ++ / CLIのdelete.NETクラスと同じように、C ++ / CLIで手動で破棄できます。
// C ++ / CLI ref class MyClass { public : MyClass (); //コンストラクタ 〜MyClassの(); //(決定論的)デストラクタ(IDisposable.Dispose()として実装)protected : !MyClass (); //ファイナライザー(非決定論的デストラクタ)(Finalize()として実装)public : static void Test () {
MyClass 自動; //ハンドルではなく、初期化なし:コンパイラはここでコンストラクタを呼び出します
MyClass ^ user = gcnew MyClass ();
ユーザーを削除し ます;
//自動がスコープ外になると、コンパイラは自動のデストラクタを呼び出します } };
演算子のオーバーロード
演算子のオーバーロードは、標準のC ++と同様に機能します。すべての*は^になり、すべての&は%になりますが、重要な追加を除いて、構文の残りの部分は変更されません。.NETクラスの場合、演算子のオーバーロードは、クラス自体だけでなく、それらのクラスへの参照に対しても可能です。この機能は、.NETrefクラスから期待される演算子のオーバーロードのセマンティクスをrefクラスに与えるために必要です。(逆に、これは、.NET Frameworkの参照クラスの場合、参照演算子のオーバーロードがC ++ / CLIで暗黙的に実装されることが多いことも意味します。)
たとえば、演算子==を使用して2つの異なる文字列参照(String ^)を比較すると、2つの文字列が等しい場合は常にtrueになります。ただし、演​​算子のオーバーロードは静的です。したがって、Object ^にキャストすると、オーバーロードのセマンティクスが削除されます。
//参照演算子のオーバーロードの影響String ^ s1 = “abc” ; 文字列 ^ s2 = “ab” + “c” ; オブジェクト ^ o1 = s1 ; オブジェクト ^ o2 = s2 ; s1 == s2 ; // true o1 == o2 ; // false
C ++ / C#の相互運用性
C ++ / CLIを使用すると、C ++プログラムはC#DLL内のC#プログラムを使用できます。ここで、#usingキーワードは、コンパイルメタデータ用にDLLが配置されているコンパイラを示します。この簡単な例では、データのマーシャリングは必要ありません。
#include “stdafx.h” 名前空間 システムを使用する; #using “… MyCS.dll”INT メイン(配列<システム::文字列 ^> ^引数) { 二重 X = MyCS ::クラス1 ::追加(40.1 、 1.9 )。 0を返す ; }
MyCS.DLLのC#ソースコードコンテンツ。
名前空間 MyCS { public class Class1 {
public static double add (double a 、 double b ) {
return a + b ;
} } }
この例は、文字列がC ++文字列からC#から呼び出し可能な文字列にマーシャリングされ、次にC ++文字列に戻る方法を示しています。文字列マーシャリングは、文字列の内容をさまざまな環境で使用できるフォームにコピーします。
#include #include #include #include “stdafx.h” 名前空間 システムを使用する; #using “..MyCS.dll”int main () { std :: string s = “I am cat” ; システム::文字列^ clrString = msclr ::相互運用:: marshal_as <システム::文字列^> (s ); // C# システムから使用可能な文字列:: String ^ t = MyCS :: Class1 :: process (clrString ); // C#関数を呼び出します std :: string cppString = msclr :: interop :: marshal_as < std :: string > (t ); // C ++から使用可能な文字列 std :: cout << "Hello、C ++ / C#Interop!" << std :: endl ; std :: cout << cppString << std :: endl ; 0を返す ; }
C#コードは、C ++に対応し
名前空間 MyCS { パブリック クラス のClass1 {
パブリック 静的 文字列 処理(列 A ) {
戻り A 。(”cat” 、”dog” )+ “をしっぽに置き換えます” ; } } }
C ++ / C#の相互運用性により、C ++は.NET機能の全世界に簡単にアクセスできます。
C ++ / CX
WinRTを対象とするC ++ / CXは、完全にアンマネージコードを生成しますが、COM「オブジェクト」に類似したWinRTの参照カウントコンポーネントのrefおよび^構文を借用します。
参考文献
^ C ++構文アップグレードチェックリストのマネージ拡張-MSDNライブラリ ^ C ++相互運用機能の使用(暗黙のPInvoke) ^ C ++ / CXデザインの内部-VisualC ++チームブログ-サイトホーム-MSDNブログ
外部リンク
ECMA 372:C ++ / CLI言語仕様
ハーブサッター:C ++ / CLIキーワード:内部
ハーブサッター:C ++ / CLIの理論的根拠
C ++ / CLIのMSDNドキュメント
キーワードの空白に関する特許出願
C ++ / CLIに関するBjarneStroustrup(C ++の設計者/作成者)の見解
スタンリーB.リップマン:こんにちは、C ++ / CLI
Stanley B. Lippman:C ++ / CLIがCLIタイプのテンプレートとCLI汎用メカニズムの両方をサポートする理由

投稿日:
カテゴリー: C