Está en la página 1de 50

Common Language Runtime

Dr. Diego Lz. de Ipiña Gz. de Artaza


Common Language Runtime
 EL Common Language Runtime es el
núcleo de la plataforma .NET.
 Es el responsable de la gestión y ejecución
del código compilado para la plataforma
.NET (código gestionado).
Common Language Runtime
 Estos son algunos de los servicios y
características que provee el CLR:
 Integración multilenguaje: El CLR permite integrar
código escrito en un lenguaje con código escrito en
otro (CLS)
 Depuración y administración de servicios: El CLR
provee de los mecanismos necesarios para que los
desarrolladores puedan depurar y administrar el código
gestionado.
Common Language Runtime
 Gestión de memoria: El CLR, a través de su
servicio de recolección de basuras, es el
responsable de recoger de memoria los
objetos no referenciados (Garbage
collector)
Common Language Runtime
 Vamos a ver qué no es el CLR:
 Las aplicaciones .NET no son interpretadas por
una “maquina virtual”: El CLR compila el
código MSIL a código máquina nativo.
 El CLR no está limitado a la plataforma
Microsoft: Es “técnicamente” posible portar el
CLR a otras plataformas hardware, así como a
otros SO.
Proyecto Mono: http://www.go-mono.com/
Anatomía de las aplicaciones .NET
 Tenemos 3 entidades principales:
 Ensamblado o Assembly que es la unidad
principal de desarrollo de .NET.
 Módulos o Modules que son los ficheros
individuales que conforman un
ensamblado.
 IL es el código del programador que
conforma el módulo.
Anatomía de las aplicaciones .NET
Assembly o Ensamblado
Manifest
Module
Metadata
IL
Tipos
Ensamblado o Assembly
 Un ensamblado es una agrupación lógica
de uno o más módulos o ficheros de
recursos (ficheros .GIF, .HTML, etc.) que se
engloban bajo un nombre común.
 Es la unidad de trabajo del CLR.
 Permiten abstraerse de la ubicación física
del código o de los recursos.
Ensamblado o Assembly
 Todo ensamblado contiene un manifiesto, que son
metadatos con información sobre las características del
ensamblado:
 Identidad (nombre, versión...)
 Nombres de los ficheros del ensamblado
 Clave hash de todos los ficheros
 Detalles sobre los tipos definidos en el ensamblado
(accesibilidad desde otros...)
 Nombres y hashes de otros ensamblados
 Permisos de seguridad
 Una lista de los tipos de datos exportados desde otros ficheros
Ensamblado o Assembly
 Dos tipos de ensamblado:
 Privados: Solo es usado por una aplicación que se
encuentra en la misma subcarpeta. Es el tipo que
crea el compilador por defecto.
También llamadas weakly named assemblies
 Públicos o compartidos: Son ensamblados creados
para ser usados por cualquier aplicación. Se
almacenan en la caché global de ensamblado.
Deben ser strongly named (contiene la clave pública y
firma digital del que publica).
Ensamblado o Assembly
 Ventajas de los ensamblados:
 No hace falta instalación.
Los ensamblados son auto-descriptivos (manifiesto).
 Versionado.
Eliminan el infierno de las DLLs.
 Ensamblados públicos frente a registro a nivel
de máquina.
Módules o Modules
 Los módulos son ficheros que pueden ser de dos
tipos:
 ficheros o módulos de recursos(ficheros.gif, .html, etc.).
 ficheros o módulos de código compilado(código MSIL).
 En la plataforma .NET se distinguen tres tipos de
módulos de código compilado:
 Ejecutables (ficheros.exe) .
 Librerías de enlace dinámico (ficheros.dll).
 Módulos que conforman un ensamblado
(ficheros.netmodule)
Módules o Modules
 Ambos ficheros contienen definiciones de tipos de
datos y tan solo los primeros (ejecutables) tienen
un punto de entrada a partir del que es posible
ejecutar el código.
 A ambos tipos de módulos se les suele llamar
ejecutables portables (PE), ya que su código
puede ser ejecutado por un CLR de cualquier
plataforma siempre que se encuentren en un
ensamblado (en estos momentos tan solo familia
Windows).
Módules o Modules
 Un módulo de código compilado se
compone de:
 Cabecera de CLR que le informa de si es un
módulo gestionado, la versión del CLR que
necesita, su firma digital...
 Los metadatos que son información sobre los
tipos definidos en su código.
 Código MSIL.
Microsoft Intermediate Language
(MSIL)
 Todos los compiladores que generan código
para la plataforma .NET generan código
escrito en un lenguaje intermedio conocido
como MSIL.
 De esta forma, MSIL es el único código que
el CLR comprende.
Herramientas de la plataforma

Csc.exe
Vbc.exe
MSIL
 MSIL facilita la ejecución multiplataforma y la
integración entre lenguajes al ser
independiente de la CPU.
 La CPU solo ejecuta código nativo luego
alguien tiene que encargarse de transformar
este código MSIL en código nativo para la
CPU.
MSIL
 De esto se encarga un componente del CLR
conocido como compilador JIT (Just-In-Time) o
jitter que va convirtiendo dinámicamente el código
MSIL a ejecutar en código nativo según sea
necesario.
 Este jitter se distribuye en tres versiones:
 Normal
 Económico
 Prejitter
Jitter Normal
 Es el que se suele usar por defecto, y sólo
compila el código MSIL a código nativo a
medida que va siendo necesario.
 Así se ahorra tiempo y memoria al evitarse
tener que compilar innecesariamente código
que nunca se ejecute.
Jitter Normal
 El cargador de clases del CLR sustituye
inicialmente las llamadas a métodos de las nuevas
clases que vaya cargando por llamadas a
funciones auxiliares (stubs) que se encarguen de
compilar el verdadero código del método.
 Una vez compilado, la llamada al stub es
sustituida por una llamada directa al código ya
compilado, con lo que posteriores llamadas al
mismo no necesitarán compilación.
Jitter Económico
 Funciona de forma similar al jitter normal solo que
no realiza ninguna optimización de código al
compilar sino que traduce cada instrucción MSIL
por su equivalente en el código máquina sobre la
que se ejecute.
 Se utiliza en dispositivos empotrados con poca
memoria y potencia de CPU.
 Aunque genere código más ineficiente es menor el
tiempo y memoria que necesita para compilar.
Jitter Económico
 Para ahorrar memoria este jitter puede descargar
código ya compilado que lleve cierto tiempo sin
ejecutarse y sustituirlo de nuevo por el stub
apropiado.
 Por estas razones, este es el jitter usado por defecto
en Windows CE, sistema operativo que se suele
incluir en los dispositivos empotrados antes
mencionados.
Prejitter
 Permite compilar completamente cualquier
ejecutable o librería (cualquier ensamblado en
general) que contenga código gestionado y
convertirlo a código nativo.
 De este modo posteriores ejecuciones del mismo
se harán usando esta versión ya compilada y no se
perderá tiempo en hacer la compilación dinámica.
Herramientas de la plataforma

Ngen.exe
Compilación dinámica
 La compilación dinámica supone que la aplicación
se ejecute más lentamente.
 Es una solución más eficiente que la utilizada en
Java donde se interpreta cada código.
 Permite que el jitter tenga más información sobre
la máquina que un compilador tradicional
pudiendo optimizar el código generado para ella
(usando instrucciones para PentiumIV, registros
extra...)
Metadatos del Módulo
 Los metadatos son un conjunto de datos
organizados en forma de tablas que pueden
almacenan información sobre:
 Tipos definidos en el módulo.
 Los miembros de estos tipos.
 Tipos externos a los que se hace referencia.
 El compilador los genera automáticamente al
crear el módulo.
Metadatos del Módulo
 Los metadatos de un módulo pueden ser
consultados a través del espacio de nombres
System.Reflection de la FCL.
 También podemos añadir información
adicional en los metadatos a través de los
atributos.
Integración Multilenguaje
 Una de las características avanzadas de la
plataforma .NET es la integración
multilenguaje.
 Podemos integrar aplicaciones escritas en un
lenguaje de la plataforma con código escrito
en otro lenguaje.
 Para ello vamos a ver dos conceptos
fundamentales: CTS y CLS.
Common Type System (CTS)
 El Common Type System (CTS) o Sistema de
Tipo Común es el conjunto de reglas que han de
seguir las definiciones de tipos de datos para que
el CLR las acepte.
 Aunque cada lenguaje gestionado disponga de
sus propia sintaxis para definir tipos de datos, en
el MSIL resultante de la compilación de sus
códigos fuente se ha de cumplir las reglas del
CTS.
Common Type System (CTS)
 Algunos ejemplos de estas reglas son:
 Cada tipo de dato puede constar de cero o
más miembros. Cada uno de estos
miembros puede ser un campo, un método
una propiedad o un evento. 
 No puede haber herencia múltiple, y todo
tipo de dato ha de heredar directa o
indirectamente de System.Object.
Clasificación de tipos del CTS
Tipos

Valor Referencia

Auto-
Predefinidos Punteros Interfaces
descriptivos

De usuario Clases Arrays

Enumera
De usuario Boxed Delegados
ciones
Tipos del CTS
 El CTS clasifica los tipos en dos bloques:
 Por valor: Se almacenan en la pila. Todos los datos de
tipo por valor descienden de System.ValueTypes
el cuál desciende de System.Object.
 Por referencia: Se almacenan en el Heap (montón de
datos). Todos los datos de los tipos por referencia
descienden directamente de System.Object.
Tipos por valor
Montón Montón Montón
gestionado gestionado gestionado

Instancia

Pila Pila Pila

El CLR necesita Se reserva Cuando se sale del


crear una memoria en la ámbito de la
instancia de un pila variable, su
tipo por valor espacio de
memoria se libera
Tipos por referencia
Montón Montón Montón
gestionado gestionado gestionado

Instancia

Heap Heap Heap

El CLR necesita Se reserva Cuando se sale del


crear una memoria en la ámbito de la
instancia de un pila variable, su
tipo por valor espacio de
memoria se libera
Valor vs. Referencia
 Diferencias:
 Liberación de memoria:
 Los tipos por referencia hay que eliminarlos explícitamente del
montón (GC).
 Asignación:
 La asignación de tipos por referencia copia direcciones de
memoria.
 Comparación de igualdad:
 La comparación de tipos por referencia compara direcciones de
memoria.
.NET built-in types I
NET C# VB.NET IL Valor o Referen.
System.Boolean bool Boolean bool Valor
System.Byte byte Byte unsigned int8 Valor
System.Char char Char char Valor
System.DateTime - Date - Valor
System.Decimal decimal Decimal - Valor
System.Double double Double float64 Valor
System.Int16 short Short int16 Valor
System.Int32 int Integer int32 Valor
.NET built-in types II
NET C# VB.NET IL Valor o Referen.
System.Int64 long Long int64 Valor
System.Object object Object Object Reference
System.SByte sbyte - int8 Valor
System.Single float Single float32 Valor
System.String string String string Reference
System.UInt16 ushort - unsigned int16 Valor
System.UInt32 uint - Unsigned int32 Valor
System.UInt64 ulong - Unsigned int64 Valor
.NET built-in types III
 Como vemos CTS es un sistema de tipos independiente del
lenguaje de programación
 No todos los tipos son soportados en cada lenguaje, por
ejemplo Date:
 En esos casos se puede usar el tipo .NET directamente:
System.DateTime d = System.DateTime.Now;
 CLS define un subconjunto de tipos de CTS que pueden ser
usadas cuando se definen librerías multi-lenguaje
 Tipos no compatibles con CLS no son soportados por algunos lenguajes
 Importante añadir atributo CLSCompliant a código para que el
compilador verifique los tipos usados
Tipos personalizados
 EL Common Type System no sería muy
flexible si no permitiese al programador
crear sus propios tipos de datos.
 Podremos definir tipos de datos
personalizados tanto por valor como por
referencia.
C# class y struct I
 Generalmente creamos un tipo personalizado a través de una clase:

public class Persona {


public Persona(string nombre, string apellido1, int edad) {
Nombre = nombre;
Apellido1 = apellido1;
Edad = edad;
}
public readonly string Nombre;
public readonly string Apellido1;
public readonly int Edad;
public bool Equals(Persona temp) {
if (temp.Nombre == this.Nombre && temp.Apellido1 == this.Apellido1 && temp.Edad ==
this.Edad) {
return true;
} else {
return false;
}
}
}
...
Persona p = new Persona(“Diego”, “Ipiña”, 29);
Persona p1 = p; // p == p1
Persona p2 = new Persona(“Diego”, “Ipiña”, 29); // p != p2
C# class y struct II
 Podemos crear nuevos tipos por valor a través de struct:

public struct Point {


public Point(int x, int y) {
this.x = x;
this.y = y;
}
private int x;
private int y;
}
...
Point p = new Point(10,20);
Concepto boxing/unboxing
 Para asegurar que “todo sea un objeto”, .NET ofrece un tipo por
referencia por cada tipo por valor
 A esto se le denomina boxed type del tipo por valor
int i = 123;
object o = i;
 CLR creará un nuevo objeto conteniendo una copia de i en el heap,
una referencia al objeto se guardará en o.
 Para hacer un unbox de un tipo por referencia se usa casting:
int i = (int)o;
 Se generará InvalidCastException si se trata de hacer un
unbox de un tipo incompatible

v.Add(3); // se permite gracias al concepto de boxing


v.Add(new Int32(3));
System.Object
 Es la clase base de la cual todos los tipos por referencia de .NET
derivan
 Provee los siguientes métodos:
 Equals: verifica si dos instancias son iguales (implementación por
defecto evalúa igualdad por referencia)
 Finalize: ejecutado automáticamente cuando un objeto es
destruido. En c# este método no aparece y se usa ~NombreObjeto
como en C++
 GetHashCode: produce un código hash del objeto, usado para
guardar un objeto en una HashTable
 GetType: devuelve el tipo de un objeto, posible a través de
capacidades de Metadata en .NET
 ReferenceEquals: verifica si dos instancias son idénticas
 ToString: devuelve una representación en forma de string del
objeto
Ejemplo System.Object
public class Pixel {
public Pixel(byte x, byte y) {
this.x = x;
this.y = y;
}
private byte x;
private byte y;
public override string ToString() {
// return “(x,y)”
return “(“ + x + “,” + y + “)”;
}
public override bool Equals(object o) {
try {
Pixel p = (Pixel)o;
return p.x == x && p.y == y;
} catch (Exception) {
return false;
}
}
public override int GetHashCode() {
return (x<<8) + y;
}
}
...
Pixel p = new Pixel(200, 150);
Console.WriteLine(p);
Common Language Specification
(CLS)
 Es un conjunto de reglas que han de seguir
las definiciones de tipos que se hagan
usando un determinado lenguaje
gestionado si se desea que sean
accesibles desde cualquier otro lenguaje
gestionado.
 Forman un subconjunto del CTS.
Common Language Specification
(CLS)
 Sólo es necesario seguir estas reglas en las
definiciones de tipos y miembros que sean
accesibles externamente, y no la en las de
los privados.
 Si no importa la interoperabilidad entre
lenguajes tampoco es necesario seguirlas.
Código accesible
 Para crear código accesible a través de
otros lenguajes debemos hacer dos
cosas:
 Seguir las reglas definidas en la
especificación del CLS.
 Marcar el código a compartir como
compartible a través del atributo
CLSCompliantAttribute.
Ejemplos
 Variable por valor y por defecto
 Directorio: 2-ejemplovalorref
 Interoperatibilidad
 Directorio: 3-interoperabilidad
 Creando un multi-file assembly
Multi-file Assembly
 Vamos a crear un assembly que consiste de
dos clases:
 SimpleMath en VB.NET con métodos Add y
Substract
 ComplexMath en C# con método Square
 Físicamente la assembly consistirá de:
 Simple.netmodule con SimpleMath
 Complex.netmodule con ComplexMath
 Math.dll que contiene el manifiesto
Multi-file Assembly
 Pasos para crear la assembly:
1. Crear Complex.cs (4-multifileassembly\Weak)
2. Compilarlo: csc /target:module complex.cs
3. Crear Simple.vb con: vbc /target:module simple.vb
4. Crear una assembly con AL (Assembly Linker) como:
al /target:library /out:Math.dll
simple.netmodule complex.netmodule
5. Crear MathDemo.cs
6. Compilar MathDemo con: csc /target:exe
/reference:math.dll mathdemo.cs
7. Ejecutar mathdemo.exe

También podría gustarte