¿Cómo funciona el trabajo externo en C #?

Cada vez que miro lo suficientemente profundo en el reflector me encuentro con métodos extern sin fuente. Leí 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 tienen que ser inyectados. Interpreté esto para decir que funciona algo así como un patrón abstracto de fábrica. También noté que nunca había visto un método externo no estático. ¿Es la statement estática un requisito (podría ver cómo esto tendría sentido)? Todavía estoy adivinando aquí y no estoy seguro de cómo funciona realmente. Me parece que el comstackdor debe reconocer ciertos atributos que mitigan el procesamiento, pero no sé cuáles son los atributos que no sean los 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 boost el rendimiento. Además, ¿cómo voy a buscar en el origen de métodos Object.InternalGetEquals() como Object.InternalGetEquals() ?

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


Cuando una statement de método incluye un modificador extern, se dice que ese método es un método externo. Los métodos externos se implementan externamente, por lo general utilizando un idioma distinto de C #. Debido a que una statement de método externo no proporciona una implementación real, el método-cuerpo de un método externo simplemente consiste en un punto y coma. Un método externo puede no ser genérico. El modificador externo se usa generalmente junto con un atributo DllImport, lo que permite implementar métodos externos mediante DLL (bibliotecas de vínculos dynamics). El entorno de ejecución puede admitir otros mecanismos mediante los cuales se pueden proporcionar implementaciones de métodos externos. Cuando un método externo incluye un atributo DllImport, la statement del método también debe incluir un modificador estático.


¿Cómo alguien aprovecha el atributo externo?

  • Escribe tu código en el idioma no administrado que elijas.
  • Compile en una DLL, exportando el punto de entrada de su código.
  • Cree una biblioteca de interoperabilidad que defina el método como un método externo en la DLL dada.
  • Llámalo desde C #.
  • ¡Lucro!

¿Cómo voy a buscar la fuente de métodos externos como Object.InternalGetEquals ()?

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

Los métodos marcados extern con el atributo [DllImport] generalmente son llamadas a las 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 ti aquí, aunque a veces necesitarías administrar la memoria manualmente. Si se equivoca la firma, su progtwig puede fallar en la llamada, puede introducir una fuga o el método puede devolver algo completamente diferente, ¡así que tenga cuidado! Encuentro pinvoke.net un gran instrumento para corregir firmas para diferentes API.

Algunos métodos extern dentro de .NET Framework que no tienen el atributo [DllImport] pero están decorados con el [MethodImpl (MethodImplOptions.InternalCall)] suelen ser los que se implementan en 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 dice MSDN 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 del lenguaje común.

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

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

Usamos el modificador “extern” en la statement del método. Se usa 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 C # se gestionan con este atributo. Si está utilizando el modificador extern, debe incluir el siguiente espacio de nombres:

using System.Runtime.InteropServices;

La syntax es algo así como:

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