C ++ CLIを簡潔かつ迅速に理解する

そのため、必要に応じてC ++ / CLIを集中的に使用する必要があり、それに応じて初心者にこれがどのように機能するのか、どのように使用するのか、そして何故なのかをよく説明します。 そのため、時間の経過とともに、言語の概要、いくつかの一般的な質問への回答、レーキが成功する場所を示す記事を書きたいという要望がありました。



これは何ですか





Microsoftが.Netプラットフォームを作成したとき、プログラマーがいくつかの既存の言語でそのために記述できるようにすることを決定しました。 後者についてです。 もっと正確に言えば、私の記憶が私に適切に役立つなら、初版では、言語はマネージ拡張付きのC ++と呼ばれていました。 その名前は、本質を暗示しています-ここでは、拡張機能を備えたプラスを提供し、ソース言語のすべての力を残しながら、すでによく知られているC ++を使用して.Net向けに開発できるようになりました。 実際、構文拡張の最初のバージョンは完全に少しひどく、コードをZhirinovskyとChernomyrdinの間の対話をエンコードして空間に送信する試みのように見せました。

//

public __gc class Class1

{

public :

// , int

int Method1(__gc int &refValue, __gc int [] managedArr);

};



* This source code was highlighted with Source Code Highlighter .






さらに、この構文では、ネイティブ型とマネージ型へのポインターの違いはなく(どちらの場合も「*」が使用されました)、ヌルポインターを示すキーワードなどはありませんでした。 これにより、Microsoftは言語の新しいリビジョンを作成するようになりました。これについては、この記事で説明します。

注:これら2つのバージョンの構文は、奇妙なことに「古い構文」と「新しい構文」と呼ばれ、プロジェクトのコンパイル設定で使用できます。 ただし、新しいアセンブリを作成するときは、新しい構文を使用することをお勧めします。古い構文は廃止され、単に悪いとマークされているからです。



なぜ必要なのですか?





1)この言語の助けを借りて、真空の球状のプログラマーは、お気に入りのプラスで本格的な.Netアプリケーションを開発できます。 正直なところ、この変質者を想像するのは難しいですし、MicrosoftがC ++で視覚的なコンポーネントを実行しなくても、明らかにこのアプローチに貢献していません。 実際、彼はそれを正しく行います。そのような目的のために、より表現力のある言語、同じC#があるからです。 したがって、これは理論的な可能性です。



2)プロで作成されたコードを呼び出すことができます。 実際、通常のC ++のすべての機能がまだあるため、ネイティブプラスの既存のクラスのマネージラッパーを作成できます。 これにより、クラスの操作方法がわからないPInvokeよりも、アンマネージコードを呼び出す機会が多くなります。



3)パフォーマンスが重要なC ++ CLIでモジュールを作成できます。 確かに、.Netの言語の動物園全体の中で、C ++は、メモリの割り当てと解放、およびポインターの操作を直接使用するコードを記述できるという点で独特です。 たとえば、次のように:

// , .Net–

public ref Class1

{

public :

// .Net-

void Method1();

{

BYTE *buff = new BYTE[100];



//do smth



delete[] buff;

}

};




* This source code was highlighted with Source Code Highlighter .








どのように機能しますか?





すべてが非常に簡単です。 C ++ / CLIでコードをコンパイルすると、MSILコードとマシンインストラクションの両方を含むアセンブリが取得され、「クリーン」プラスで記述された行が変換されます。 「しかし、クロスプラットフォームについてはどうでしょうか?」と尋ねると、あなたは絶対に正しいでしょう。 まさか。 特に、これは、32ビット版と64ビット版の同じバイナリを収集できないことを意味します(「すべてのCPU」の下ですべてを収集するため)。 これは、C ++のすべての機能を使用するために支払われる価格です。 当然、これはマネージコードとアンマネージコードが混在して使用される場合を指します。 いくつかのコンパイルオプションがあります。

•/ clr-新しい構文を使用したマネージコードとネイティブコードのサポート。

•/ clr:pure-ネイティブコードはサポートされていません。 ただし、たとえば安全でないディレクティブを使用してC#アセンブリで実行できる範囲で、安全でないコードを使用できます。

•/ clr:safe-管理された安全なコードのみ。 アナログは、安全ではないC#アセンブリをコンパイルしています。

/ clr:oldSyntax-/ clrの類似物で、古い構文のみが使用されます。



どのように見えますか?





C#とC ++ / CLIの基本的な構成を比較する例を次に示します。



クラス宣言


C#:
public sealed class Class1 : Class2



* This source code was highlighted with Source Code Highlighter .






C ++ / CLI:
public ref class Class1 sealed : Class2



* This source code was highlighted with Source Code Highlighter .








構造宣言


C#:
public struct Class1 : IEquatable



* This source code was highlighted with Source Code Highlighter .






C ++ / CLI:
public value class Class1 : IEquatable



* This source code was highlighted with Source Code Highlighter .








インターフェース発表


C#:
public interface ISomeInterface



* This source code was highlighted with Source Code Highlighter .






C ++ / CLI:
public interface class ISomeInterface



* This source code was highlighted with Source Code Highlighter .








上場発表


C#:
public enum Enum1

{

Val1,

Val2

}



* This source code was highlighted with Source Code Highlighter .






C ++ / CLI:
public enum class Enum1

{

Val1,

Val2

}



* This source code was highlighted with Source Code Highlighter .








管理対象エンティティの作成


C#:
object obj = new object ();



* This source code was highlighted with Source Code Highlighter .






C ++ / CLI:
Object ^obj = gcnew Object();



* This source code was highlighted with Source Code Highlighter .






C ++ / CLIでは、「*」の代わりに「^」を使用して、管理対象オブジェクトを参照します。 後で削除する必要があるオブジェクトと不要なオブジェクトを区別することは非常に便利です。 また、ローカル参照オブジェクトを作成するときに、スタックのセマンティクスを使用できます。

オブジェクトobj();

これは、IDisposableを実装するオブジェクト(これについては後で説明します)を使用する場合、または値の型に対して使用する場合に意味があります。 値型の保存と使用に関して、プログラマはリンクを使用するか値を使用するかを選択できるため、C ++ / CLIはC#よりも自由度が高いことに注意してください。 したがって、状況によっては、ボックス化/ボックス化解除操作の回数を節約することができます。



マネージドアレイの作成


C#:
object [] arr = new object [100];



* This source code was highlighted with Source Code Highlighter .






C ++ / CLI:
array<Object ^> ^arr = gcnew array<Object ^>();



* This source code was highlighted with Source Code Highlighter .






アンマネージアレイは通常どおり作成されます。



メソッドにパラメーターを渡す


C#:
void Method( int byValue, ref int byRef, out int outValue);



* This source code was highlighted with Source Code Highlighter .






C ++ / CLI:
void Method( int byValue, int %byRef, [ out ] int %outValue);



* This source code was highlighted with Source Code Highlighter .






この例からわかるように、「^」が通常のC ++の「*」に類似している場合、「%」は「&」に類似しています。 さらに、類推は非常に正確であり、パラメーターを渡すときだけでなく、たとえば次のようなリンクを受け取るときにもトレースできます。

void Method(ValueType val)

{

ValueType ^ ref = %val;

}




* This source code was highlighted with Source Code Highlighter .








メソッドのオーバーライド


C#:
override void Method();

* This source code was highlighted with Source Code Highlighter .






C ++ / CLI
virtual void Method() override ;



* This source code was highlighted with Source Code Highlighter .








IDisposableテンプレートの実装


C#:

class Class1 : Disposable

{

public void Dispose()

{

this .Dispose( true );



GC.SuppressFinalize( this );

}



protected virtual void Dispose( bool disposing)

{

if (disposing)

{

//release managed resources

}



//release unmanaged resources

}



~Class1()

{

this .Dispose( false );

}

}



* This source code was highlighted with Source Code Highlighter .






C ++ / CLI:

ref class Class1

{

public :

// Dispose

~Class1()

{

//release managed resources



//call finalizer

this ->!Class1();

}



//

!Class1()

{

//release unmanaged resources

}

}




* This source code was highlighted with Source Code Highlighter .






C ++ / CLIでは、コンパイラはDisposableテンプレートの一部を実装しており、これはインターフェースの典型的な実装とは外観が異なります。 さらに、同じコンパイラーでは、IDisposableを直接実装することはできません。 ただし、それに慣れると、この動作は非常に論理的であり、繰り返しコードを大量に記述する必要がなくなることを理解できます。 また、リソースのリリースを通常のC ++と同様にしたいという要望から、この言語の作成者はさらに進んで、次の2つの方法でDisposeを明示的に呼び出すことができます。

obj->~Class1();



* This source code was highlighted with Source Code Highlighter .






そして

delete obj;

* This source code was highlighted with Source Code Highlighter .






スタックのセマンティクスを使用して、リソースのクリーニングを保証することもできます。

C ++ / CLI:

{

A();



Class1 obj;



B();

}



* This source code was highlighted with Source Code Highlighter .




に対応

C#:

{

A();



using (Class1 obj = new Class1())

{

B();

}

}



* This source code was highlighted with Source Code Highlighter .








舞台裏に残っているものは何ですか?





1つの記事にすべてを入れることは不可能であったことは明らかです。 次のような質問:

•デリゲート、プロパティ、拡張メソッド、foreachなどの構文。

•オブジェクト、配列などを使用して、マネージドからアンマネージドへ、またはその逆へのジャグリング。

•サポートされているものであり、C#および通常のC ++のものではない

•C ++ / CLIアセンブリを使用してアプリケーションをコンパイルする機能

•パフォーマンスの問題。 いつ、どのように勝つことができますか? どこで突然失うことができますか?



何を読む?





1. C#とC ++構文の比較: www.cyberforum.ru/cpp-cli/thread83662.html

2.主な特定の言語構成要素: msdn.microsoft.com/en-us/library/xey702bw.aspx

3. C ++ / CLIへの移行: msdn.microsoft.com/en-us/library/ms235289.aspx



おわりに





.Netの他のすべての言語の中で、C ++ / CLIは非常に具体的です。 その上で標準の.Netアプリケーションを開発することはほとんど意味がありませんが、既存のC ++コードとの通信として、または最適化タスクのために、そうです。



All Articles