Zėŋōfōbìå

24 gennaio 2009

Reflection in C: enum

Filed under: C#, informatica, Linguaggi — Tag:, , — Zeno @ 10:58

Comincio a descrivere un metodo e una libreria che sto riscrivendo che permette di ottenere funzionalità di reflection in C.
Ho trovato interessante la tecnica X-Macro, descritta da JP nel suo articolo di Blog e ho deciso di adottarla in questa nuova versione.
Nella mia versione precedente, descritta al NNLD 08, utilizzavo un preprocessore scritto in awk, uno script esterno all’ambiente di sviluppo, che eseguiva un parsing del codice riconoscendo keyword utili a costruire files c autogenerati utili a fornire metodi di reflection.
Al termine della presentazione Massimiliano Mantione mi ha suggerito di utilizzare, per ottenere gli stessi risultati senza uscire dall’ambiente di sviluppo, il preprocessore C.
Questo che segue è una possibile soluzione.

L’esempio che voglio presentare è composto da 5 files.

file authors.def, che contiene l’elenco degli elementi che compongono l’enum Authors:

#define AUTHORS
ENUM_START(Authors) \
EFIELD(Adams) \
EFIELD(Asimov) \
ENUM_END(Authors) \

file meta_def.h, si usa per costruire la definizione dell’enum :

#define ENUM_START(a) typedef enum {
#define EFIELD(a) a,
#define ENUM_END(a) a ## _LAST } a;

file meta_descr.h, serve a costruire un array di stringhe, una per ogni campo dell’enum

#define ENUM_START(a) char* a ## _descr []= {
#define EFIELD(a) #a,
#define ENUM_END(a) "LAST" };

file meta.h, contiene le definizioni utili per estrarre la descrizione di un enum.

#ifndef META_H
#define META_H

#define ENUM_GET_DESCR(a,b) a ## _descr [ b ]

#endif

file main.c, mostra un uso possibile della libreria.

#include "meta.h" // libreria meta
#include "authors.def" // include la macro AUTHORS, che definisce l'elenco di campi dell'enum authors.

// La macro AUTHORS viene espansa in modo diverso, a seconda che si voglia ottenere la definizione dell'enum oppure la descrizione dell'enum

// definizione dell'enum
#include "meta_def.h"
AUTHORS

//descrizione dell'enum
#include "meta_descr.h"
AUTHORS

int main()
{
        Authors a;
        for(a=Adams; a

risultato:

Zeno@Spring ~/src/metac
$ gcc -E main.c

typedef enum { Adams, Asimov, Authors_LAST } Authors;
char* Authors_descr []= { "Adams", "Asimov", "LAST" };

int main()
{
 Authors a;
 for(a=Adams; a

L'output:


Zeno@Spring ~/src/metac
$ ./a.exe
0: Adams
1: Asimov

Annunci

2 commenti »

  1. Hello. :D

    Non so perchè ma saoevo che ti sarebbe tornato utile il discorso sulle XMacro… :D

    Tutto molto interessante: poi ti chiederò i dettagli. :D

    Commento di jp — 25 gennaio 2009 @ 9:22

  2. Sto cercando di espandere la reflection alle strutture, usando la stessa tecnica.
    Probabilmente avrò bisogno delle liste, o meglio ancora delle hashtable, ho trovato un’ottima implementazione (le liste tratte dal kernel di linux, le hashtable non saprei) a partire da: http://isis.poly.edu/kulesh/stuff/src/ .

    Commento di Fabrizio — 26 gennaio 2009 @ 14:05


RSS feed for comments on this post. TrackBack URI

Rispondi

Effettua il login con uno di questi metodi per inviare il tuo commento:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

Crea un sito o un blog gratuitamente presso WordPress.com.

%d blogger hanno fatto clic su Mi Piace per questo: