example - Escribiendo struct en el archivo de memoria mapeado(mmap)
mmap c (2)
En primer lugar, debe hacer un seguimiento de la memoria que desea escribir, segundo, debe recordar que la memoria mapeada es como cualquier otro puntero a la memoria. El último bit es importante, ya que esto significa que puede utilizar la indexación de matriz normal para acceder a la memoria, o utilizar funciones como memcpy
para copiar en la memoria.
Para escribir una estructura, tienes tres opciones:
Escribe la estructura tal como está, como en un archivo binario. Esto significará que tiene que
memcpy
la estructura a una posición especificada.Escriba la estructura, campo por campo, como texto usando, por ejemplo,
sprintf
en la posición correcta.Trate la memoria como una cadena grande, y haga, por ejemplo,
sprintf
de cada campo en un buffer temporal, luegostrcat
para agregarlo a la memoria.
Tengo un problema para escribir struct en un archivo de memoria mapeado.
Tengo dos archivos, a saber, mmap.write.c y mmap.read.c, y en estos archivos, estoy escribiendo un número entero en un archivo y lo leo desde el archivo.
Cuando quiero escribir struct y leerlo, no puedo pensar en eso desde la línea 32 de mmap.write.c
sprintf((char*) file_memory, "%d/n", i);
y en la línea 25 de mmap.read.c
sscanf (file_memory, "%d", &integer);
No hay diferencia para escribir y leer entero / doble / flotante / char, etc. ya que puedo poner el patrón como segundo argumento "% d" para entero. ¿Pero qué voy a escribir aquí para indicar struct? Ese es mi principal problema.
La estructura que quiero escribir y leer:
#define CHANNELS 20
typedef dataholder struct {
int value[CHANNELS];
time_t time;
int hash;
}dataholder;
mmap.read.c
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include "mmap.h"
#define FILE_LENGTH 0x10000
int main (int argc, char* const argv[])
{
int fd;
void* file_memory;
int integer;
/* Open the file. */
fd = open (argv[1], O_RDWR, S_IRUSR | S_IWUSR);
printf("file opened/n");
/* Create the memory mapping. */
file_memory = mmap (0, FILE_LENGTH, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0);
printf("memfile opened/n");
close (fd);
printf("file closed/n");
/* Read the integer, print it out, and double it. */
while(1) {
sscanf (file_memory, "%d", &integer);
printf ("value: %d/n", integer);
usleep(100000);
}
//sprintf ((char*) file_memory, "%d/n", 2 * integer);
/* Release the memory (unnecessary because the program exits). */
munmap (file_memory, FILE_LENGTH);
return 0;
}
mmap.write.c
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
#include "mmap.h"
#define FILE_LENGTH 0x10000
/* Return a uniformly random number in the range [low,high]. */
int random_range (unsigned const low, unsigned const high)
{
unsigned const range = high - low + 1;
return low + (int) (((double) range) * rand () / (RAND_MAX + 1.0));
}
int main (int argc, char* const argv[])
{
int fd, i;
void* file_memory;
/* Seed the random number generator. */
srand (time (NULL));
/* Prepare a file large enough to hold an unsigned integer. */
fd = open (argv[1], O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
//lseek (fd, FILE_LENGTH+1, SEEK_SET);
write (fd, "", 1);
//lseek (fd, 0, SEEK_SET);
/* Create the memory mapping. */
file_memory = mmap (0, FILE_LENGTH, PROT_WRITE, MAP_SHARED, fd, 0);
close (fd);
/* Write a random integer to memory-mapped area. */
for(i=0; i<10000; i++) {
sprintf((char*) file_memory, "%d/n", i);
//goto a;
usleep(100000);
}
a:
/* Release the memory (unnecessary because the program exits). */
munmap (file_memory, FILE_LENGTH);
return 0;
}
Muchas gracias por adelantado.
La forma más sencilla es usar un puntero:
dataholder *dh = file_memory;
/* now you can access dh->value, dh->time, dh->hash */
Como esta estructura no contiene punteros, si necesita copiarla o sacarla, simplemente puede asignarla, como:
dataholder dh_other = *dh;
o
*dh = dh_other;