¿Cómo funciona extern en C#?


Cada vez que miro lo suficientemente profundo en reflector me encuentro con extern métodos sin fuente. He leído la documentación de msdn en http://msdn.microsoft.com/en-us/library/e59b22c5 (v=vs.80). aspx . Lo que obtuve de ese artículo es que los métodos con el modificador extern deben inyectarse. Interpreté esto en el sentido de que funciona algo así como un patrón de fábrica abstracto. También me di cuenta de que nunca he visto un método externo no estático. Es la declaración estática un requisito (pude ver cómo esto tendría sentido)? Todavía estoy adivinando aquí y no estoy seguro de cómo funciona en realidad. Me parece que el compilador debe reconocer ciertos atributos que mitigan el procesamiento, pero no se cuales son los atributos que he encontrado como MethodImplAttribute y DllImportAttribute del ejemplo de MSDN. ¿Cómo alguien aprovecha el atributo extern? Dijo que en muchos casos esto puede aumentar el rendimiento. Además, ¿cómo podría investigar la fuente de extern métodos como Object.InternalGetEquals()?

Author: smartcaveman, 2011-02-25

4 answers

Considere leer la sección 10.6.7 de la especificación de C#, que responde a muchas de sus preguntas. Reproduzco parte de ella aquí para su conveniencia:


Cuando una declaración de método incluye extern modificador, ese método se dice ser un método externo. Externo los métodos se implementan externamente, por lo general, el uso de un lenguaje que no sea C#. Porque un método externo declaration provides no actual aplicación, el método-cuerpo de una método externo simplemente consiste en un coma. Un método externo no puede ser genérico. El modificador externo es normalmente se utiliza junto con un Atributo DllImport, permitir que los métodos externos sean implementado por DLL (Dynamic Link Biblioteca). El entorno de ejecución puede apoyar otros mecanismos mediante los cuales: implementaciones de métodos externos se puede proporcionar. Cuando un externo el método incluye un atributo DllImport, la declaración del método también debe incluir una estática modificador.


¿Cómo alguien aprovecha el atributo extern?

  • Escriba su código en el lenguaje no administrado de su elección.
  • Compílelo en una DLL, exportando el punto de entrada de su código.
  • Cree una biblioteca interop que defina el método como un método externo en la DLL dada.
  • Llámelo desde C#.
  • Beneficio!

¿Cómo podría investigar la fuente de métodos externos como Objeto.InternalGetEquals()?

Ir a https://github.com/dotnet/coreclr/tree/master/src/vm

 88
Author: Eric Lippert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-19 20:00:31

Métodos marcados extern con [DllImport] los atributos suelen ser llamadas a bibliotecas C. Esta característica es útil para llamar a WinAPI o código heredado.

Este es un ejemplo 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);
   }
}

Llama a MessageBox que se define dentro de la biblioteca de Windows user32.dll. Runtime hace todo el trabajo pesado por usted aquí, aunque a veces tendría que administrar manualmente la memoria. Si obtiene la firma incorrecta, su programa puede fallar en la llamada, puede introducir una fuga o el método puede devuelva algo completamente diferente, así que tenga cuidado! Encuentro pinvoke.net un gran instrumento para corregir firmas para diferentes APIs.

Algunos métodos extern dentro de. NET Framework que no tienen [DllImport] atributo, pero están decoradas con [MethodImpl (MethodImplOptions.InternalCall)] los atributos suelen ser los implementados en el propio CLR, que también está escrito en C. Algunos de estos métodos simplemente no se pueden implementar en C# porque administran el tiempo de ejecución en sí, y algunos se implementan en C porque su rendimiento es crítico y C es más rápido.

Esto es lo que MSDN dice sobre ellos:

Especifica una llamada interna. Una llamada interna es una llamada a un método que se implementa dentro del tiempo de ejecución de common language.

En cuanto a mirar el código de implementación real, dudo que pueda obtenerlo de Microsoft, pero hay algunas implementaciones alternativas geniales de CLR alrededor de, así que asegúrese de comprobarlas.

 25
Author: Dan Abramov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-16 21:24:38

extern es con invocación de plataforma (pinvoke) para facilitar las llamadas de ensamblados administrados a código no administrado. La palabra clave extern informa al compilador que necesitará generar el código correcto para permitir la correcta clasificación de datos.

 3
Author: Matthew Whited,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-24 21:36:05

Usamos el modificador "extern" en la declaración del método. Se utiliza para indicar que el método se implementa externamente. Un uso común del modificador "extern" es con el atributo DllImport. Las llamadas a funciones que no son de C# se gestionan con este atributo. Si está utilizando extern modifier entonces usted tiene que incluir el siguiente espacio de nombres:

using System.Runtime.InteropServices;

La sintaxis es algo como:

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

 1
Author: Andy Rocks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-05 11:59:11