8

構造体をマップされたメモリ ファイルに書き込む際に問題があります。

mmap.write.c と mmap.read.c という 2 つのファイルがあり、これらのファイルでは、整数をファイルに書き込み、ファイルから読み取ります。

struct を書いて読みたい時、mmap.write.c の 32 行目以降で考えられませんでした。

sprintf((char*) file_memory, "%d\n", i);

mmap.read.c の 25 行目

sscanf (file_memory, "%d", &integer);

integer/double/float/char などの書き込みと読み取りに違いはありません。これは、整数の 2 番目の引数 "%d" としてパターンを指定できるためです。しかし、構造体を示すためにここに何を書きますか? それが私の主な問題です。

読み書きしたい構造体:

#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;
}

よろしくお願いします。

4

2 に答える 2

13

まず、書き込みたいメモリの場所を追跡する必要があります。次に、マップされたメモリが他のメモリへのポインタとまったく同じであることを覚えておく必要があります。最後のビットは重要です。これは、通常の配列インデックスを使用してメモリにアクセスしたり、メモリmemcpyにコピーするなどの機能を使用したりできることを意味します。

構造を作成するには、次の3つの選択肢があります。

  1. バイナリファイルのように、構造をそのまま記述します。これはmemcpy、指定された位置に構造を配置する必要があることを意味します。

  2. sprintfたとえば正しい位置に使用して、構造をフィールドごとにテキストとして記述します。

  3. メモリを1つの大きな文字列として扱い、たとえばsprintf各フィールドを一時バッファに入れstrcatてから、メモリに追加します。

于 2013-01-15T12:22:38.470 に答える
4

最も簡単な方法は、ポインターを使用することです。

dataholder *dh = file_memory;
/* now you can access dh->value, dh->time, dh->hash */

この構造体にはポインターが含まれていないため、コピーインまたはコピーアウトする必要がある場合は、次のように割り当てることができます。

dataholder dh_other = *dh;

また

*dh = dh_other;
于 2013-01-15T12:22:45.837 に答える