web-dev-qa-db-fra.com

Comment fonctionne extern en C #?

Chaque fois que j'examine suffisamment le réflecteur, je rencontre des méthodes extern sans source. J'ai lu la documentation msdn sur http://msdn.Microsoft.com/en-us/library/e59b22c5 (v = vs.80) .aspx . Ce que j'ai obtenu de cet article, c'est que les méthodes avec le modificateur extern doivent être injectées. J'ai interprété cela comme signifiant que cela fonctionne quelque chose comme un modèle d'usine abstrait. J'ai également remarqué que je n'avais jamais vu de méthode externe non statique. La déclaration statique est-elle une exigence (je pouvais voir en quoi cela aurait du sens)? Je suis encore en train de deviner ici et je ne sais pas comment cela fonctionne réellement. Il me semble que le compilateur doit reconnaître certains attributs qui limitent le traitement, mais je ne sais pas quels sont les attributs autres que ceux que j'ai rencontrés comme MethodImplAttribute et DllImportAttribute du MSDN Exemple. Comment utilise-t-on l'attribut extern? Il a déclaré que dans de nombreux cas, cela peut augmenter les performances. De plus, comment pourrais-je rechercher la source des méthodes extern comme Object.InternalGetEquals()?

59
smartcaveman

Pensez à lire la section 10.6.7 de la spécification C #, qui répond à bon nombre de vos questions. J'en reproduis une partie ici pour votre commodité:


Lorsqu'une déclaration de méthode inclut un modificateur externe, cette méthode est dite être une méthode externe. Les méthodes externes sont implémentées en externe, en utilisant généralement un langage autre que C #. Étant donné qu'une déclaration de méthode externe ne fournit aucune implémentation réelle, le corps de méthode d'une méthode externe se compose simplement d'un point-virgule. Une méthode externe peut ne pas être générique. Le modificateur extern est généralement utilisé en conjonction avec un attribut DllImport, permettant aux méthodes externes d'être implémentées par des DLL (bibliothèques de liens dynamiques). L'environnement d'exécution peut prendre en charge d'autres mécanismes grâce auxquels des implémentations de méthodes externes peuvent être fournies. Lorsqu'une méthode externe inclut un attribut DllImport, la déclaration de méthode doit également inclure un modificateur statique.


Comment quelqu'un exploite-t-il l'attribut extern?

  • Écrivez votre code dans la langue non gérée de votre choix.
  • Compilez-le dans une DLL, exportez le point d'entrée de votre code.
  • Créez une bibliothèque d'interopérabilité qui définit la méthode comme une méthode externe dans la DLL donnée.
  • Appelez-le depuis C #.
  • Profit!

Comment pourrais-je rechercher la source des méthodes externes comme Object.InternalGetEquals ()?

Accédez à https://github.com/dotnet/coreclr/tree/master/src/vm

96
Eric Lippert

Les méthodes marquées extern avec l'attribut [DllImport] sont généralement des appels aux bibliothèques C. Cette fonctionnalité est utile pour appeler WinAPI ou un code hérité.

Voici un exemple de 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);
   }
}

Il appelle MessageBox qui est défini dans la bibliothèque Windows user32.dll. Le runtime fait tout le travail lourd pour vous ici, bien que parfois vous deviez gérer manuellement la mémoire. Si la signature est incorrecte, votre programme peut échouer lors de l'appel, vous pouvez introduire une fuite ou la méthode peut renvoyer quelque chose de complètement différent, alors soyez prudent! Je trouve pinvoke.net un excellent instrument pour corriger les signatures des différentes API.

Certaines méthodes extern dans .NET Framework qui n'ont pas d'attribut [DllImport] mais sont décorées avec [MethodImpl (MethodImplOptions.InternalCall)] Les attributs sont généralement ceux implémentés dans CLR lui-même, qui est également écrit en C. Certaines de ces méthodes ne peuvent tout simplement pas être implémentées en C # car elles gèrent le runtime lui-même, et certaines sont implémentées en C car leurs performances sont critiques et C est plus rapide.

C'est ce que MSDN dit à leur sujet:

Spécifie un appel interne. Un appel interne est un appel à une méthode qui est implémentée dans le runtime de langage commun lui-même.

En ce qui concerne le code d'implémentation réel, je doute que vous puissiez l'obtenir auprès de Microsoft, mais il existe quelques implémentations alternatives intéressantes de CLR alors assurez-vous de les vérifier.

29
Dan Abramov

extern est avec invocation de plateforme (pinvoke) pour faciliter les assemblys managés appelant du code non managé. Le mot clé extern informe le compilateur qu'il devra générer le code correct pour permettre le bon marshaling des données.

3
Matthew Whited

Nous utilisons le modificateur "extern" dans la déclaration de méthode. Il est utilisé pour indiquer que la méthode est implémentée en externe. Une utilisation courante du modificateur "extern" est avec l'attribut DllImport. Les appels de fonction non C # sont gérés avec cet attribut. Si vous utilisez un modificateur externe, vous devez inclure l'espace de noms suivant:

using System.Runtime.InteropServices;

La syntaxe est quelque chose comme:

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

2
Andy Rocks