2012-06-22 17 views
21

BCLの多くのメソッドは、[MethodImpl(MethodImplOptions.InternalCall)]属性でマークされています。 indicates "メソッドが共通言語ランタイム自体の中で実装されている"こと。MethodImplOptions.InternalCallのポイントは何ですか?

このように、実行時に強制される明示的な明示的なCIL命令を持つことでフレームワークを設計する点は何ですか?最終的に、属性はランタイムの契約上の義務を作成していますが、わかりやすくわかりやすくわかりやすく表示されます。

例えば、Math.Powはこの方法(それが悪い場合C#+ ILおよびIL自体の私の非公式の混合物を言い訳;これは私のポイントを説明するための唯一のサンプルです)書かれている可能性:

public static double Pow(double x, double y) 
{ 
    ldarg.0 
    ldarg.1 
    pow // Dedicated CIL instruction 
    ret 
} 

を現在の方法の代わりに:

[MethodImpl(MethodImplOptions.InternalCall)] 
public static double Pow(double x, double y); 

なぜMethodImplOptions.InternalCallが存在するのですか?

+6

それはうまくいかないようではなく、ちょうど恐ろしくスケールする。スタックトランザクションはILオペコードに対して暗黙的であり、機能シグネチャを処理するために多くのツールを更新する必要があります。宣言がメタデータにあるときは無料です。また、Ecma-335規格を超えて容易に拡張できます。 –

+0

@Hans:新しいIL命令のサポートを追加することについての質問はありましたか?私はAniが最初に「InternalCall」メソッドがそこにあった理由を知りたいと思った。ちょうど尋ねる... –

+1

@thecoon - '//専用のCIL命令'は良いヒントです。 –

答えて

7

新しいIL命令を作成することは非常に難しく、外部命令(ILGenerator、ilasm、ildasm、PEVerify、Reflector、PostSharp、...)を含む多くのツールに影響する可能性があると思います。

しかし、新しいInternalCallメソッドを作成しますか?これは、C#でメソッドを記述するのと同じくらい簡単です(私はRotorを検証するためには見なかったと仮定します)、何も影響しません。

それを作成するだけではなく、メンテナンスにも同じことが当てはまります。

+0

申し訳ありませんが、私はコメントを投稿しましたが、正しく答えました。+1。 –

+0

@スヴィク:十分に公正。あなたは.NETの最初のリリース以来、Math.Powについて話していますか? ECMA規格を過度に複雑にしたくないというHansの主張は、その理由であろうか? – Ani

+0

@Aniこれは、ILで何かをやっているほとんどの人にとって、もっと多くの仕事を意味します。その作業がツールの最初のバージョンに移行しなければならないという事実はあまり変わらない。 – svick

3

私はそれがCLRを過度に複雑にしないと思った。最初にCILを調べると、アセンブリ言語との類似点や、限られた命令セットがプロセッサ上で直接実行されたように見えるようになりました。

理論上、CLR JITのサンプルコードがPowの場合は、pow命令のネイティブコードを発行する必要があります(これはネイティブ命令がないためですか?数年前から新しいx86命令セットが登場しました)。パフォーマンスの観点から見ても、実装の観点から見ても、powコードのmscorlibを呼び出すだけで、インラインで貼り付けるよりもずっと簡単です。

または、一般的なmscorlib関数のルックアップテーブルがInternalCallであり、その命令を関数自体の呼び出しで置き換えることができます。しかし、もう一度、すべてではないInternalCallそのように簡単です。

私は便宜上トレードオフだと思います。 CLRのメンテナンス性、より統一されたCLI標準、および発信者にある程度の柔軟性を可能にするため、

ボトムラインは私がCLRを開発しておらず、これはちょうど私の頭の上から外れていることです。私がやっただろうと思うもの。

1

このメソッドは、ネイティブのTRULYネイティブで、ランタイム自体に実装されています。結局のところ、CLRはC++から来ていることを忘れないでください。コンパイラに似ています。現実の世界では、CILは本当に実行されていません。それはJIT-tedであり、コンパイラのようにC/C++ランタイムによって実行されます。 Math.PowはおそらくネイティブのC/C++のmath.h powメソッドへの呼び出しであり、実装定義されています。今ではNETとMonoがCLRを実装しています。

UnityEngine.dllでは、ほとんどのネイティブの外部メソッドで[MethodImpl(MethodImplOptions.InternalCall)]が使用されます。しかし、これらのC++メソッドはMono C++ CLRライブラリを直接使用し、P/INVOKE自体よりも密接な方法でC#と協調することができます。そして、よりパフォーマンスの高い方法(実装の詳細を隠して理解しにくくする)

ただし、を使用する唯一の方法は、CLRランタイムそのものです。 MicrosoftのCLR実装を変更することさえ可能かどうかは分かりませんが、Monoではこの機能を悪用することは自由です。

また、これを[MethodImpl(MethodImplOptions.Unmanaged)]と混乱させないでください。これはまったく別の話です。

内部コールに関する

ますますモノが、ここでどのように機能するか:http://www.mono-project.com/docs/advanced/embedding/

免責事項:私はUnityまたはモノラルに関連していないのです!

関連する問題