Re: Question de C : simuler un FILE

Top Page

Reply to this message
Author: Edgar Bonet
Date:  
To: guilde
Subject: Re: Question de C : simuler un FILE
Bonjour !

Frédéric a écrit :
> Je suis en train d'adapter un code de parser midi sur un STM32 [...]
> Je pensais loger le fichier MIDI en RAM, dans un tableau : y a-t-il
> ensuite un moyen de parcourir ce tableau comme s'il s'agissait d'un
> fichier ?


Si je comprends bien, le code va tourner sur le STM32, et tu veux
pouvoir utiliser les fonctions de stdio.h (fopen() et cie.) pour lire un
tableau en RAM, c'est bien ça ?

Si c'est ça, ça va dépendre de l'implémentation de la libc qui tu
utilises sur cette plateforme. Je ne connais pas les libc pour
microcontrôleur ARM mais, juste à titre d'exemple, avr-libc te permet de
définir toi même les opérations de lecture et écriture de fichiers. À la
place de fopen(), tu as la fonction

    FILE* fdevopen(int(*put)(char, FILE *), int(*get)(FILE *));


où c'est toi qui fournis les fonctions put() et get() pour écrire et
lire un octet à la fois. Libre à toi de définir fopen() à partir de là
si tu veux.

Autre exemple, la GNU libc te fournit la fonction fmemopen(), qui fait
exactement ce que tu veux et est POSIX.1-2008.

Regarde la doc de ta libc, il y a peut-être quelque chose d'adapté.

Sinon, l'autre alternative et de définir toi même les fonctions de
stdio.h. Par exemple:

------------------------------------------------------------------------
/***********************************************************************
* stdio.h
*/

typedef struct {
    const char *start, *end, *pos;
} FILE;


FILE *fopen(const char *pathname, const char *mode);


/***********************************************************************
* stdio.c.
*/

#include <string.h>

/*
* File my-file.mid embedded as a resource with:
*
* ld -r -b binary my-file.mid -o my-file.o
*/
extern const char _binary_my_file_mid_start[];
extern const char _binary_my_file_mid_end[];

FILE file_resource = {
    .start = _binary_my_file_mid_start,
    .pos = _binary_my_file_mid_start,
    .end = _binary_my_file_mid_end
};


FILE *fopen(const char *pathname, const char *mode)
{
    (void) mode;  // only reading is supported
    if (strcmp(pathname, "my-file.mid") != 0)
        return NULL;  // we know no other file
    file_resource.pos = file_resource.start;
    return &file_resource;
}
------------------------------------------------------------------------


L'implémentation des autres fonctions est laissée à titre d'exercice.
;-)

À+,

Edgar.

[1] https://www.nongnu.org/avr-libc/user-manual/group__avr__stdio.html