El último paso es crear una vista concreta sobre la proyección de archivos. La vista representa una porción del objeto proyección al que tendremos acceso a través de un puntero. Podemos crear una vista completa del archivo (un puntero al inicio), desde la mitad, una vista de 100 KB, etc.
Windows permite crear múltiples vistas sobre una misma proyección, incluso desde distintos procesos. La dirección de memoria retornada por la vista puede apuntar al mismo bloque de memoria virtual (en sistemas Windows 95/98/Me siempre es así), o a distintas zonas de memoria virtual (aunque realmente se proyectan sobre la misma memoria física).
La función que debemos utilizar para crear vistas es la siguiente:
LPVOID MapViewOfFile(
HANDLE hObjetoProyección,
objeto proyección
DWORD dwTipoAcceso, tipo de acceso a la vista
DWORD dwDesplazamientoHigh,
desplazamiento (32 bits altos)
DWORD dwDesplazamientoLow, desplazamiento (32 bits bajos)
DWORD dwTamaño
nº de bytes de la vista
);
Y ahora la explicación:
- hObjetoProyección: indica el descriptor del objeto proyección que previamente hemos obtenido a través de la función OpenFileMapping o CreateFileMapping.
- dwTipoAcceso: indica el modo de acceso que se va a hacer sobre los datos de la vista. Los valores admitidos son los mismos que para la función OpenFileMapping.
- dwDesplazamientoHigh: contiene los 32 bits más altos del desplazamiento inicial. Si se indica un cero en este parámetro, se utilizará el valor pasado en dwDesplazamientoLow.
- dwDesplazamientoLow: contiene los 32 bits más bajos del desplazamiento inicial. El desplazamiento indica la posición a partir del inicio del archivo en que comenzará la vista, o dicho de otro modo: el incremento del puntero desde el principio del archivo. Para obtener el desplazamiento total, de combinará este valor con el indicado en dwDesplazamientoHigh. El único problema con el uso de estos parámetros, es que el valor combinado debe ser múltiplo de la granularidad de reserva. Este valor se obtiene a través de la función GetSystemInfo, en el campo dwAllocationGranularity de la estructura SYSTEM_INFO, aunque en plataformas x86 tiene un valor de 64.
- dwTamaño: indica el tamaño en bytes de tendrá la vista. Más allá de este tamaño, no se podrá acceder a los datos. Si se indica 0 en este parámetro, se creará una vista sobre el archivo completo.
La función retorna un puntero al inicio de la zona de memoria que representa la vista, o NULL si se produce algún tipo de error.
Si proyectamos varias vistas sobre la misma proyección, no se nos garantiza que la dirección retornada por MapViewOfFile sea la misma, ya que el sistema buscará el lugar más adecuado para crear la vista.
Además de esta función, existe una versión extendida (MapViewOfFileEx), en la que se añade un nuevo parámetro: lpDirecciónBase. Este parámetro (un puntero genérico), nos permite indicar la dirección de inicio para la vista. Esta dirección de inicio debe ser múltiplo del valor dwAllocationGranularity, del que ya hablamos anteriormente. La función retornará la dirección de inicio de la vista, que será el valor que hemos pasado en ldDirecciónBase, o el múltiplo de 64 KB inmediatamente anterior. Si en la dirección indicada no es posible crear la vista (por falta de espacio o cualquier otro motivo), se retornará NULL.
Esta función es útil para crear una vista en una posición fija, y que cualquier proceso acceda directamente a esta dirección (abriendo la proyección previamente), para leer los datos del archivo proyectado.
Una vez que hemos terminado con los datos de la vista, es necesario cerrarla para liberar los recursos asociados. Esto se hace a través de la función UnmapViewOfFile:
BOOL UnmapViewOfFile(
LPCVOID lpDirecciónBase dirección de la vista
);
En este caso la función es muy sencilla, símplemente debemos pasar la dirección de una vista previamente creada (el valor retornado por MapViewOfFile).
Windows garantiza que todas las páginas que sean modificadas y no hayan sido todavía guardadas en el archivo, se volcarán al archivo proyectado, aunque esto sólo es así cuando se ha creado una proyección sobre un archivo físico, y no sobre el archivo de paginación del sistema.
De todas formas, en cualquier momento podemos forzar a que Windows almacene el contenido de las páginas modificadas en el archivo físico, a través de la la siguiente función:
BOOL FlushViewOfFile(
LPCVOID lpDirecciónBase,
DWORD dwNumeroBytes
);
Esta función también es sencilla, símplemente se nos pide la dirección a partir de la que queremos grabar, y el número de bytes totales.
Nos retornará TRUE si las páginas han sido grabadas con éxito, o FALSE si ha ocurrido algún error.
Bueno, estas son las funciones disponibles para el manejo de archivos proyectados en memoria. Ahora vamos a profundizar en uno de los usos más importante de los archivos proyectados: la comunicación entre procesos.