Visualizzazione dei risultati da 1 a 9 su 9
  1. #1

    [C] Gestione importazione librerie

    Ciao a tutti,

    Sono di nuovo qua a chiedervi consigli su conversione di codice da python a C, abbiate pazienza. Cercherò di essere il più chiaro possibile...

    Python:

    codice:
     
    import a,b,c
    import costanti
    
    _moduli = { costanti.COSTANTE_1 : a,
    costanti.COSTANTE_2: b,
    costanti.COSTANTE_2: c }
    
    def qualcosa()
          for modulo in _moduli.itervalues():
              modulo._reset()
    In sostanza vorrei replicare, in maniera "fine" e non eccessivamente spaghetti code, questa situazione.
    In sostanza all'interno dei moduli a,b,c è presente, in ognuno, una propria funzione di reset.
    Premesso che l'intenzione sarebbe quella di creare 3 file (a.h, b.h, c.h; le cui funzioni si chiameranno, ad esempio, a_reset(), a_stampa(), b_reset(), b_stampa() ) ciò che più mi preoccupa è cercare di fare un for decente nel sorgente principale; ovvero non dover ricorrere ad una funzione che faccia:

    codice:
    void resetta_moduli()
    {
     a_reset();
     b_reset();
     c_reset();
    }
    Consigli? Spero di essere stato il più chiaro possibile.

    Un saluto a tutti

  2. #2
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    707
    Non so se ho capito bene, perché è proprio semplicissimo.
    codice:
    class Modulo():
        def reset(self):
            raise NotImplementedError
    
    class Modulo1(Modulo):
        def reset(self):
            print "modulo 1 reset"
            
    class Modulo2(Modulo):
        def reset(self):
            print "modulo 2 reset"        
            
    a = Modulo1()
    b = Modulo2()
    moduli = [a, b]
    
    for m in moduli:
        m.reset()
    EDIT: ho corretto perché forse avevo frainteso

  3. #3
    Ho riletto il mio post iniziale e mi sono reso conto di aver omesso di voler replicare il codice python in ansi c..
    Scusatemi

  4. #4
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    707
    Non ho capito bene il problema comunque.

    Anche in C se si vuole richiamare una o più funzioni in diversi files, il metodo corretto sarebbe dichiarare una struttura (modulo_st) che contiene uno o più puntatori a funzione. Quindi In ogni file si crea una struttura modulo_st e gli si assegna quella/e funzione. A questo punto puoi fare un array di questi moduli e iterararli chiamando la funzione che ti pare.

  5. #5
    In C++ si farebbe inserendo in ogni modulo una classe specifica che eredita da una superclasse comune, e definendo i metodi virtuali appropriati nella superclasse; puoi quindi creare un vettore di puntatori ai vari oggetti e richiamare i metodi virtuali che ti interessano (tra cui reset).

    In C la questione è un po' più complicata, perché ti devi implementare a mano questo genere di cose. Una possibilità sarebbe avere una struct di puntatori a funzione contenente le varie funzioni "comuni" ai vari moduli; ogni modulo che tiri dentro ha una funzione che consente di inizializzare in maniera appropriata la struct in questione, quindi "da fuori" puoi richiamare le funzioni di ogni modulo usando tramite questi puntatori a funzione.

    Esempio:
    codice:
    /* interface.h */
    #ifndef INTERFACE_H_INCLUDED
    #define INTERFACE_H_INCLUDED
    
    typedef int (*stampaFnPtr)(int Param1, int Param2);
    typedef void (*resetFnPtr)(void);
    /* ... altre ... */
    
    struct ModuleInterface
    {
        printFnPtr stampaFn;
        resetFnPtr resetFn;
        /* ... */
    };
    #endif
    
    /* a.h */
    #ifndef A_H_INCLUDED
    #define A_H_INCLUDED
    #include "interface.h"
    
    int a_stampa(int Param1, int Param2);
    void a_reset(void);
    
    void a_initInterface(struct ModuleInterface * Interface);
    
    #endif
    
    /* a.c */
    
    void a_initInterface(struct ModuleInterface * Interface)
    {
        Interface.stampaFn = &a_stampa;
        Interface.resetFn = &a_reset;
        /* ... */
    }
    
    /* ... */
    
    /* ... idem per gli altri moduli ... */
    
    /* main.c */
    #include "interface.h"
    #include "a.h"
    #include "b.h"
    #include "c.h"
    
    #define ARRSIZE(arr)    (sizeof(arr)/sizeof(*(arr)))
    
    struct ModuleInterface modules[3];
    
    void initModuli()
    {
        /* solo qui devi fare il lavoro per ogni modulo */
        a_initInterface(&module[0]);
        b_initInterface(&module[1]);
        c_initInterface(&module[2]);
        /* questo lavoro tra l'altro si può automatizzare con una macro */
    }
    
    /* poi puoi chiamare le varie funzioni semplicemente ciclando sull'array modules */
    void resetModuli()
    {
        for(int i=0; i<ARRSIZE(modules); i++)
            modules[i].reset();
    }
    Amaro C++, il gusto pieno dell'undefined behavior.

  6. #6
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    707
    Faccio il mio esempio in C, che mi sembra ancora più semplice di quello di Mitaly

    codice:
    /* modulo.h */
    
    #ifndef MODULO_H
    #define MODULO_H
    
    struct modulo_st {
        void (*start)();
        void (*stop)();
    };
    
    #endif
    
    /* modulo a.c */
    
    #include <stdio.h>
    #include "modulo.h"
    
    void a_start()
    {
        printf("a start\n");
    }
    
    void a_stop()
    {
        printf("a stop\n");
    }
    
    struct modulo_st modulo_a = {
        a_start,
        a_stop
    };
    
    /* modulo b.c */
    
    #include <stdio.h>
    #include "modulo.h"
    
    void b_start()
    {
        printf("b start\n");
    }
    
    void b_stop()
    {
        printf("b stop\n");
    }
    
    struct modulo_st modulo_b = {
        b_start,
        b_stop
    };
    
    /* main.c */
    
    #include <stdio.h>
    #include "modulo.h"
    
    extern struct modulo_st modulo_a, modulo_b;
    
    int main()
    {
        struct modulo_st *moduli[] = { &modulo_a, &modulo_b, NULL };
        int i;
        
        for (i = 0; moduli[i] != NULL; i++)
            moduli[i]->start();
    
        for (i = 0; moduli[i] != NULL; i++)
            moduli[i]->stop();        
    
        return 0;
    }

  7. #7
    Vi ringrazio entrambi.
    Avete colto pienamente nel segno!


    Passo ad implementare, nel caso abbia dubbi o problemi non esiterò a disturbarvi ancora

  8. #8
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    707
    Aggiungo solo che i vari metodi del modulo (in quelli che ho chiamato a.c e b.c)
    è buona norma mettere lo specificatore "static".
    Non l'ho fatto per non aggiungere altra carne al fuoco.

    Come magari ben sai, in C mettere "static" prima della dichiarazione del metodo
    ne riduce la visibilità all'interno del file.
    In questo modo puoi direttamente chiamare i metodi "start" e "stop" in tutti i moduli
    senza che ci sia sovrapposizione di nomi.

  9. #9
    Originariamente inviato da c0der
    Aggiungo solo che i vari metodi del modulo (in quelli che ho chiamato a.c e b.c)
    è buona norma mettere lo specificatore "static".
    Non l'ho fatto per non aggiungere altra carne al fuoco.

    Come magari ben sai, in C mettere "static" prima della dichiarazione del metodo
    ne riduce la visibilità all'interno del file.
    In questo modo puoi direttamente chiamare i metodi "start" e "stop" in tutti i moduli
    senza che ci sia sovrapposizione di nomi.
    Sì, credo anch'io che sia un'ottima idea (e in effetti la tua soluzione è decisamente meno "greve" rispetto alla mia, che pecca un po' di voler fare delle finte classi in C ).
    Originariamente inviato da tiziocaio2
    Vi ringrazio entrambi.
    Amaro C++, il gusto pieno dell'undefined behavior.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.