web-dev-qa-db-ja.com

externはC#でどのように機能しますか?

リフレクターを深く見ると、ソースのないexternメソッドにぶつかります。 http://msdn.Microsoft.com/en-us/library/e59b22c5(v = vs.80).aspx でmsdnドキュメントを読みました。私がその記事から得たのは、extern修飾子を持つメソッドを注入する必要があるということです。私はこれを、抽象的な工場パターンのように機能することを意味すると解釈しました。また、非静的externメソッドを見たことがないことにも気付きました。静的宣言は要件ですか?私はまだここで推測しており、実際にどのように機能するのか分かりません。コンパイラは処理を軽減する特定の属性を認識しなければならないように思えますが、MSDNのMethodImplAttributeDllImportAttributeのように出会った属性以外の属性が何かわかりません。例。誰かがextern属性をどのように活用しますか?多くの場合、これによりパフォーマンスが向上すると言われています。また、Object.InternalGetEquals()のようなexternメソッドのソースをどのように調べますか?

59
smartcaveman

C#仕様のセクション10.6.7を読んで、多くの質問に答えることを検討してください。便宜上、ここにその一部を複製します。


メソッド宣言にextern修飾子が含まれる場合、そのメソッドは外部メソッドと呼ばれます。外部メソッドは、通常C#以外の言語を使用して、外部で実装されます。外部メソッド宣言は実際の実装を提供しないため、外部メソッドのメソッド本体はセミコロンのみで構成されます。外部メソッドは汎用的ではない場合があります。 extern修飾子は通常、DllImport属性と組み合わせて使用​​され、DLL(ダイナミックリンクライブラリ)によって外部メソッドを実装できます。実行環境は、外部メソッドの実装を提供できる他のメカニズムをサポートする場合があります。外部メソッドにDllImport属性が含まれる場合、メソッド宣言には静的修飾子も含める必要があります。


誰かがextern属性をどのように活用しますか?

  • 選択したアンマネージ言語でコードを記述します。
  • それをDLLにコンパイルし、コードのエントリポイントをエクスポートします。
  • 指定されたDLLでメソッドを外部メソッドとして定義する相互運用ライブラリを作成します。
  • C#から呼び出します。
  • 利益!

Object.InternalGetEquals()のようなexternメソッドのソースを調べるにはどうすればよいですか?

https://github.com/dotnet/coreclr/tree/master/src/vm に移動します

96
Eric Lippert

extern_[DllImport]_ 属性でマークされたメソッドは、通常Cライブラリの呼び出しです。この機能は、WinAPIまたはレガシーコードの呼び出しに役立ちます。

これはMSDNの例です。

_using System;
using System.Runtime.InteropServices;
class MainClass 
{
   [DllImport("User32.dll")]
   public static extern int MessageBox(int h, string m, string c, int type);

   static int Main() 
   {
      string myString; 
      Console.Write("Enter your message: ");
      myString = Console.ReadLine();
      return MessageBox(0, myString, "My Message Box", 0);
   }
}
_

Windows _user32.dll_ライブラリ内で定義されているMessageBoxを呼び出します。ここでは、ランタイムがすべての重い作業を行いますが、メモリを手動で管理する必要がある場合もあります。署名が間違っていると、プログラムが呼び出しに失敗したり、リークが発生したり、メソッドがまったく異なるものを返す可能性があるため、注意してください! pinvoke.net は、さまざまなAPIの署名を修正するための優れた手段です。

_[DllImport]_ 属性を持たないが [MethodImpl (MethodImplOptions.InternalCall)] 属性で装飾された.NET Framework内のいくつかのexternメソッド通常、CLR自体に実装されているもので、CLRでも記述されています。そのようなメソッドの一部は、ランタイム自体を管理するためにC#で実装できない場合もあります。また、パフォーマンスが重要でCが高速であるため、一部はCで実装されます。

これは、MSDN says それらについてです:

内部コールを指定します。内部呼び出しは、共通言語ランタイム自体に実装されているメソッドへの呼び出しです。

実際の実装コードを見ると、Microsoftから入手できるとは思いませんが、 CLRのクールな代替実装 があるので、必ずチェックしてください。

29
Dan Abramov

extern は、アンマネージコードを呼び出すマネージアセンブリを容易にするためのプラットフォーム呼び出し(pinvoke)です。 externキーワードは、正しいデータマーシャリングを可能にするために正しいコードを生成する必要があることをコンパイラに通知します。

3
Matthew Whited

メソッド宣言では「extern」修飾子を使用します。メソッドが外部で実装されていることを示すために使用されます。 「extern」修飾子の一般的な使用法は、DllImport属性を使用することです。非C#関数呼び出しは、この属性で管理されます。 extern修飾子を使用している場合、次の名前空間を含める必要があります。

_using System.Runtime.InteropServices;_

構文は次のようなものです。

[DllImport("User32.dll")] public static extern int MessageBox(int h, string m, string c, int type);

2
Andy Rocks