2008-10-19 10 views
39

He usado C# en Visual Studio con .NET, y he jugado un poco con Mono en openSUSE Linux, pero realmente no entiendo cómo funciona.¿Cómo funciona Mono?

Si escribo una aplicación en Windows en .NET, ¿cómo se relaciona esto con Mono? No puedo simplemente ejecutar un archivo .exe de Windows en Linux sin Wine, por lo que no me ayuda a ejecutar aplicaciones desarrolladas en Windows.

¿El objetivo es simplemente tener una biblioteca .NET equivalente en Linux (y otros) para facilitar el desarrollo de plataformas cruzadas? Por ejemplo, si fuera un negocio y quisiera llegar a clientes de Linux, pero realmente quisiera usar .NET, ¿entonces Mono debería ser mi elección? ¿O hay algo más que me estoy perdiendo?

Respuesta

20

Un EXE de Windows contiene varias "partes". Simplificado, el código .net (= MSIL) es solo una parte del EXE, y también hay una parte de Windows nativa "real" dentro del EXE que sirve como un tipo de iniciador para .NET Framework que luego ejecuta el MSIL.

Mono simplemente tomará el MSIL y lo ejecutará, haciendo caso omiso de las cosas nativas de Windows Launcher.

De nuevo, esta es una descripción simplificada.

Editar: Temo a mi comprensión de los detalles profundos profundas no es lo suficientemente bueno para realmente mucho detalle (que sé más o menos lo que un encabezado PE es, pero en realidad no los detalles), pero he encontrado estos enlaces útiles:

NET Assembly Structure – Part II

.NET Foundations - .NET assembly structure

+0

alguna posibilidad de una versión un poco más detallada? :) – DavidG

+0

Me temo que mi comprensión de los detalles profundos de depp no ​​es lo suficientemente buena para eso (sé más o menos lo que es un encabezado de PE, pero no realmente los detalles), pero me parecieron útiles estos enlaces: http://is.gd/ 4n4i http://is.gd/4n4n –

+4

No hay una parte nativa de Windows "real" dentro del EXE. El encabezado es solo una descripción. Puede apuntar al punto de entrada dentro del EXE o DLL pero esto es ejecutable por el entorno host o no. El "iniciador" real es externo al ejecutable y es nativo de Windows o parte del CLR (para .NET y Mono). – Justin

10

De hecho, puede ejecutar un archivo .NET .exe con Mono en Linux. Esto no requiere vino. De hecho, Mono compila programas para archivos .exe, que pueden ejecutarse con Mono en Linux o como ejecutables en Windows.

+1

Correcto. Mono implementa el CLR (.NET) mientras Wine intenta implementar el entorno de Windows nativo completo (API de Win32 y funciones del kernel). – Justin

2

Mono es una implementación de código abierto de Microsoft de .NET CLR (Common Language Runtime). Esto es lo que funciona como parte de los programas .NET que no están en el código nativo sino en CIL (Common Intermediate Language), un lenguaje intermedio neutro en el lenguaje y en la máquina. The Runtime toma ese código intermedio y lo traduce en código máquina.

En el estado actual de Mono, puede tomar los programas .NET que usan las partes principales de .NET (mscorlib.dll) y ejecutarlos en cualquier lugar donde Mono se ejecute, no solo Windows.

2

Pero como se menciona que Mono es de código abierto y no se puede simplemente confiar en que será la implementación .NET completa, tiene algunos controles que no funcionan, también debe tener cuidado con P/Invoca que su aplicación utilizará, por ejemplo, su aplicación se comunicará con MCI (interfaz de controlador multimedia) en win32. Pero también estaba usando mono escribiendo aplicaciones GTK #, pero también he usado mis aplicaciones de Windows que funcionaron sin ninguna recompilación como mencionamos anteriormente nuestros compañeros programadores, es decir, mono es una alternativa de código abierto de .NET de Microsoft, y por defecto si está compilando aplicaciones WinForms o Gtk # que mono compilará y creará un ensamblado .exe para cada archivo, y por supuesto si lo desea, creará una Biblioteca de vínculos dinámicos (DLL), casi como lo hace en .NET. Solo como sugerencia, intente escribir algo de Gtk # (con MonoEvelop IDE que tiene su diseñador de GUI integrado llamado stetic). Y, por supuesto, mono puede ser un gran sustituto para los servicios web, puede crearlos en .NET y puede alojarlos en Apache (porque el alojamiento Linux hoy en día son más baratos que los de Windows), los servicios web y otras aplicaciones asp.net funcionarán bajo Apache con un módulo mod_mono que debe incluirse en apache.

Un poco fuera de tema pero solo quería contarles un adelanto de mi experiencia.

0

Para seguir la respuesta de Michael, creo que tendrá que volver a compilar en Mono para que la aplicación se ejecute en el tiempo de ejecución de Mono. Excepciones pueden existir. Solo jugué un poco con Mono, y siempre he compilado nuevamente la fuente. Nunca intenté ejecutar una aplicación .NET directamente en Mono.

Además, se supone que Mono 1.9 es totalmente compatible con .NET 2.0. Se supone que Mono Olive y Moonlight agregan .NET 3.0 (menos WPF) y la funcionalidad de Silverlight.

+1

Solo una nota. No es necesario que recompile una aplicación .NET para que funcione en Mono. – Justin

1

También puede echar un vistazo a MoMA (si su objetivo es portar aplicaciones de Win a Lin).

Mono Migration Analyzer (MoMA) herramienta ayuda a identificar los problemas que puede tener al portar su aplicación .Net a Mono. Ayuda a identificar llamadas específicas de la plataforma (P/Invoke) y áreas que aún no son compatibles con el proyecto Mono.

MoMA

Aquí es una aplicación web que compara los tipos de BCL ya aplicadas por Mono y .NET Framework 3,5

http://mono.ximian.com/class-status/2.0-vs-3.5/index.html

106

Ésta es una cuestión de edad (con un ya respuesta seleccionada) pero no creo que la pregunta realmente haya sido respondida correctamente.

En primer lugar, un poco de historia ...

¿Cómo funciona el .NET?

Un archivo .EXE tradicional de Windows es un archivo binario que representa una serie de instrucciones de lenguaje de máquina que su computadora entiende y que hace llamadas a la API Win32 que son partes de Windows que ofrecen servicios que las aplicaciones pueden aprovechar. El lenguaje de máquina utilizado es muy específico para su tipo de computadora y las llamadas de Win32 hacen que el ejecutable sea muy dependiente de Windows. Un ejecutable .NET no es así.

Es importante darse cuenta de que un ejecutable .NET (archivo .EXE) no es realmente una aplicación nativa de Windows. Windows mismo no entiende cómo ejecutar el código en un ejecutable .NET. Tu computadora tampoco lo entiende.

Al igual que Java, una aplicación .NET se compone de instrucciones en un lenguaje llamado CIL (Common Intermediate Language) que se puede considerar como el lenguaje de máquina para una computadora idealizada que realmente no existe. En .NET, la implementación del software de esta máquina idealizada se denomina Common Language Runtime (CLR). El equivalente en el mundo de Java se llama Java Virtual Machine (JVM). En Java, el equivalente a CIL se llama bytecode de Java. CIL a veces se llama MSIL (Microsoft Intermediate Language).

CIL está diseñado para ejecutarse en CLR (una máquina idealizada) pero es independiente de la plataforma, lo que significa que al CIL no le importa qué tipo de computadora tiene o qué sistema operativo está ejecutando.

Al igual que necesita una versión nativa de Java JVM en cada plataforma en la que desea ejecutar Java, necesita una versión nativa del CLR para ejecutar ejecutables .NET CIL. El CLR es una aplicación nativa de Windows al igual que los archivos EXE Win32 tradicionales descritos anteriormente. El CLR en sí es específico para la implementación de Windows y la arquitectura de la computadora en la que fue diseñado para ejecutarse.

No importa el lenguaje .NET con el que empiece (C#, VisualBasic, F #, IronPython, IronRuby, Boo, etc.), todos se compilan en el bytecode de CIL. Puede "desmontar" fácilmente un programa CIL en una forma de lenguaje ensamblador orientado a objetos que sea fácilmente legible para los humanos. Puedes escribir un programa directamente en CIL, pero pocas personas lo hacen.

En Windows, el CLR compila este código CIL Just-In-Time (JIT) justo cuando ejecuta el ejecutable, justo antes de ejecutar el código. Esto significa que el bytecode de CIL se convierte (compila) en código de máquina real que se ejecuta de forma nativa en su computadora. Esta parte del CLR se llama el compilador JIT o, a menudo, solo el JIT.

Hasta la fecha, Microsoft ha lanzado cuatro versiones del CLR: 1.0, 1.1, 2.0 y 4.0. Debe tener instalada la versión correcta del CLR en su máquina si desea ejecutar ejecutables .NET dirigidos a ese tiempo de ejecución. CLR 2.0 admite aplicaciones .NET 2.0, 3.0 y 3.5. Para otras versiones de .NET, la versión .NET se correlaciona limpiamente con la versión CLR.

Además de JIT/CLR, .NET proporciona una gran cantidad de bibliotecas (ensamblajes) que conforman el resto de .NET Framework y que proporcionan una cantidad de capacidades y servicios que las aplicaciones .NET pueden invocar. La gran mayoría de estos conjuntos son código CIL puro que se ejecuta en el CLR. En Windows, algunos hacen llamadas a la API de Win32 también. Cuando instala .NET, está instalando CLR, las bibliotecas de clase (framework) y un conjunto de herramientas de desarrollo. Cada versión del CLR generalmente requiere un conjunto completo de estos ensambles "marco". Algunas versiones de .NET (por ejemplo, 3.0 y 3.5) agregaron ensamblajes de marco adicionales sin actualizar el CLR o los ensamblajes existentes asociados con ese CLR.

El formato de archivo Portable Executable (PE) en el que se entrega un archivo .EXE de Windows contiene un encabezado que describe el ejecutable e identifica el archivo como un archivo .NET o un archivo Win32 nativo. Cuando Windows intenta ejecutar un archivo .NET, ve este encabezado e invoca automáticamente el CLR en su nombre. Esta es la razón por la cual los archivos .NET EXE parecen ejecutarse de forma nativa en Windows.

Ok, entonces, ¿cómo funciona Mono?

Mono implementa CLR en Linux, Mac y otras plataformas. El tiempo de ejecución de Mono (el CLR) es una aplicación nativa escrita principalmente en lenguaje C y compilada para el código de lenguaje de la máquina para el sistema informático en el que está diseñado para ejecutarse. Al igual que en Windows, el tiempo de ejecución de Mono es específico para el sistema operativo y el tipo de máquina que está utilizando.

Al igual que en Windows, el tiempo de ejecución Mono (el CLR) compila el bytecode CIL en su ejecutable de .NET Just-In-Time para el código nativo que su computadora puede entender y ejecutar. De esta forma, un archivo .NET es tan "nativo" para Linux como lo es para Windows.

Para transferir a Mono una nueva arquitectura, debe conectar el JIT/CLR. Esto es como portar cualquier aplicación nativa a una nueva plataforma.

El funcionamiento del código .NET en Linux o Mac es solo una cuestión de qué tan bien se implementa el CLR en estos sistemas. En teoría, Mono CLR podría ejecutar código .NET en estos sistemas mucho mejor que la versión MS de .NET en Windows. En la práctica, la implementación de MS es generalmente superior (aunque no en todos los casos).

Además del CLR, Mono proporciona la mayor parte del resto de las bibliotecas (asambleas) que componen el marco .NET. Al igual que con la versión de .NET de Microsoft (de hecho, más), los ensamblajes Mono se proporcionan como bytecode CIL. Esto hace posible tomar un archivo * .dll o * .exe de Mono y ejecutarlo sin modificaciones en Windows, Mac o Linux, ya que CIL es el lenguaje "nativo" de las implementaciones de CLR en estos sistemas.

Al igual que en Windows, Mono soporta múltiples versiones del CLR y los conjuntos asociados:

versiones

muy temprana de Mono (antes 1,2?) Sólo se admite CLR 1.0 o 1.1. Mono no admitía grandes fragmentos del framework 2.0 hasta su propia versión 2.0.

Las versiones mono hasta la versión 2.4 admiten las aplicaciones CLR 1.1 y CLR 2.0.

Comenzando con Mono 2.6, se agregó CLR 4.0 pero CLR 2.0 todavía era el predeterminado.

Comenzando con Mono 2.8, el CLR 4.0 se convirtió en el predeterminado y el CLR 1.1 ya no es compatible.

Mono 2.10 continúa utilizando el CLR 4.0 como predeterminado y también para admitir el CLR 2.0.

Al igual que el .NET real (pero en un número mucho menor de los casos) hay Montaje de Mono que ponen en bibliotecas nativas. Para hacer que el ensamblado System.Drawing funcione en Mono, el equipo Mono escribió un programa Linux para simular la parte GDI + de la API Win32 en Linux. Esta biblioteca se llama 'libgdiplus'. Si compila Mono desde el origen, notará que necesita construir este archivo 'libgdiplus' antes de poder construir 'mono'. No necesita 'libgdiplus' en Windows porque la parte GDI + de la API de Win32 ya es parte de Windows. Un puerto completo de Mono a nuevas plataformas requiere que esta biblioteca 'libgdiplus' sea portada también.

En áreas donde el diseño de la biblioteca .NET está excesivamente influenciado por el diseño de Windows, y una adaptación pobre para sistemas como Mac o Linux, el equipo de Mono ha escrito extensiones para .NET Framework. Las extensiones Mono también son solo bytecode CIL y generalmente funcionan bien en .NET.

A diferencia de Windows, Linux generalmente no detecta los ejecutables de .NET y ejecuta el CLR de forma predeterminada. El usuario generalmente debe ejecutar el CLR directamente escribiendo 'mono appname.exe' o algo similar. Aquí 'mono' es la aplicación que implementa el CLR y 'appname.exe' es el archivo EXE que contiene el código .NET para ser ejecutado.

Para facilitar las cosas a los usuarios, las aplicaciones Mono a menudo se envuelven en un script de shell que inicia el CLR. Esto oculta el hecho de que CLR se está utilizando igual que en Windows. También es posible decirle a Linux que inicie el CLR cuando se encuentre un archivo usando el formato de archivo PE. Por lo general, esto no se hace porque el formato de archivo PE también se usa para ejecutables nativos de Windows Win32 que, por supuesto, el CLR (Mono) no es compatible.

No hay ninguna razón técnica por la cual un iniciador PE no pueda ser utilizado por Linux, que luego inicia un sistema que entiende el código nativo de Windows (como Wine) o el CLR (Mono) según corresponda. Esto simplemente no se ha hecho a mi conocimiento.

De ida y vuelta

Cualquier código .NET que se adhiere a "totalmente administrado" de código, lo que significa que no pone en código non-.NET, debería funcionar bien en Mono en todas las plataformas. De forma rutinaria utilizo ensamblados .NET compilados desde Windows (para los cuales no tengo el código) en Linux y Mac.

También puedo tomar cualquier código que compile en Mono y ejecutarlo en .NET en Windows. Puedo proporcionarle a un cliente un código que he compilado con Mono y no preocuparme si está en Windows de 32 o 64 bits, por ejemplo. El cliente necesita tener la versión correcta de .NET (el CLR correcto) instalado por supuesto. CLR 2.0 ha existido durante mucho tiempo y puede apostar que casi todos los usuarios de Windows lo tienen instalado. Los compiladores Mono y otros códigos también son solo ejecutables CIL y funcionan bien en Windows si quieres.

La compatibilidad mono es lo suficientemente buena como para poder tomar grandes porciones de código real de Microsoft, como ASP.NET MVC (si es legal hacerlo) de la versión MS de .NET y ejecutar en Mac o Linux. En general, el equipo Mono ha hecho un gran trabajo al implementar tanto el CLR como el resto del marco (bibliotecas/ensamblajes de clase).

ASP.NET

En Windows, el Servidor de Información de Internet (IIS) sabe cómo llamar a la CLR .NET para ejecutar como parte de una aplicación web. En Linux/Mac hay un módulo Apache (mod_mono) que proporciona capacidades similares al servidor web Apache. Esta aplicación está escrita en C y también debe ser portada a nuevas arquitecturas.

Porting Mono

Esta discusión ha identificado partes de mono que se construyen como ejecutables "nativos" y debe existir en un sistema en el que desea ejecutar aplicaciones .NET.

  • El CLR (incluyendo compilador JIT) - generalmente conocido como Mono
  • libgdiplus (para sistemas que no soportan de forma nativa el GDI + API [solamente Windows no])
  • mod_mono (para permitir Apache para invocar el CLR para aplicaciones web .NET)

Estos tres componentes, con la adición de las bibliotecas de clases, proporcionan un entorno .NET que parece "nativo" a los archivos ejecutables de .NET que necesita ejecutar.

Así es como funciona Mono.

+1

muy bonito informe completo. Tener una pregunta sin embargo. Cuando ejecuta el .NET exe compilado, ¿cómo sabe el sistema operativo que necesita ejecutar un JIT a través de él o no? ¿No tiene que hacer uso de alguna hacker ejecutable PE32 que ejecute el JIT si es necesario? Pero si eso se hace, ¿sería dependiente de la plataforma? ¿Cómo usaría otra plataforma ese exe ya que no comprende PE32? – greatwolf

+1

@Victor - La estructura del archivo PE (EXE) contiene un encabezado. Una sección "opcional" de este encabezado identifica el archivo como un ejecutable de .NET. Antes de Windows XP, el cargador ejecutable no tenía conocimiento de .NET y requería una instrucción de salto nativo para invocar el CLR. Desde XP, el cargador mira el encabezado e invoca el CLR directamente (no se requiere código nativo). El CLR invoca el JIT. Para Mono, es típico invocar el CLR manualmente en el momento del inicio (por ejemplo, escribiendo 'mono somefile.exe'). El "hackeo" PE es solo la información en el encabezado. Ni Mono ni Windows modernos usan ningún código nativo del EXE. – Justin

+0

@Victor: el JIT se invoca cada vez que se ejecuta un ejecutable CIL (.NET). No se compila en el código nativo hasta el tiempo de ejecución. Es por eso que se llama "Just-in-Time". Puede hacer cosas como la compilación AOT en Mono (o usar ngen.exe en .NET) para precompilar parte del código. Este código precompilado no es portátil. Todavía se llama al JIT en tiempo de ejecución incluso entonces, pero puede usar código precompilado del "caché" si corresponde. AOT/Ngen no son típicos, aunque MonoTouch (.NET en iOS) lo requiere y usa AOT completo exclusivamente. – Justin