2010-10-01 19 views
8

Ho una struttura con una funzione di callback, la funzione di callback ha bisogno di un puntatore alla struttura per fare la sua operazione. Come definisco correttamente questi elementi tale che verrà compilato senza avvisi?Come definire correttamente un puntatore a funzione in struct, che prende struct come un puntatore?

typedef struct { 

    // some fields required for processing... 

    int (*doAction)(struct pr_PendingResponseItem *pr); 
} pr_PendingResponseItem; 

Se rimuovo l'attributo "struct" sul parametro pr, viene visualizzato un errore. Se lo lascio, ricevo un avviso: "il suo ambito è solo questa definizione o dichiarazione, che probabilmente non è quello che vuoi"

Tutto funziona, ma mi piacerebbe sapere il modo corretto per definire tale una struttura

anche legato, è la definizione di una struttura auto referenziale:

typedef struct LinkedItem_ { 
    LinkedItem_ * prev; 
    LinkedItem_ * next; 
    void * data; 
} LinkedItem; 

(credo che questo è corretto, ma i pensieri aggiuntivi sono i benvenuti, se è legato alla domanda.)

risposta

12

vostri puntatore a funzione riferimenti una struct pr_PendingResponseItem, ma non hai dichiarato una struct pr_PendingResponseItem. Hai solo una struttura senza nome digitata sul nome pr_PendingResponseItem (e quel nome non è ancora stato stabilito).

Dare lo struct un nome:

struct pr_PendingResponseItem { 

    // some fields required for processing... 

    int (*doAction)(struct pr_PendingResponseItem *pr); 
} ; 
typedef struct pr_PendingResponseItem pr_PendingResponseItem; 
3

qualcosa di simile

typedef struct _pr_PendingResponseItem_ { 

    // some fields required for processing... 

    int (*doAction)(struct _pr_PendingResponseItem_ *pr); 
} pr_PendingResponseItem; 

dovrebbe risolvere il problema.

(testato & opere)

0

Aggiunta alla risposta da nos sopra.

L'intuizione chiave qui è che quando si tratta di una dichiarazione del tipo "typedef struct nome1 nome2 {};", si sono effettivamente dichiarando due tipi vale a dire "struct NAME1 {};" e poi "typedef struct nome1 nome2;", dove "struct nome1" è un tipo e si deve usare la sintassi "struct nome1" per riferirsi ad esso, e "nome2" è un tipo, e si fare riferimento ad esso come "nome2". Ti è permesso di uscire "nome1", nel qual caso devi solo definire il secondo tipo e il primo rimane una struttura anonima.

Ora, nel primo caso, se si desidera fare riferimento al tipo "struct pr_PendingResponseItem", è necessario dichiarare tale tipo, anziché la struttura anonima dichiarata. Quindi, modifica la dichiarazione della struct in "struct pr_PendingResponseItem".

Nel secondo caso, si sta tentando di fare riferimento a un tipo di struct come riferimento avanzato (ovvero riferirsi ad esso prima che la sua definizione sia completa), che è permesso, ma per fare riferimento a un tipo di struct, la sintassi richiesta è "nome della struttura". Quindi è necessario sostituire i riferimenti successivi a "LinkedItem_" nella definizione con "struct LinkedItem_".

8

Ci sono due modi per farlo - per entrambe le strutture di esempio. Sono essenzialmente isomorfi.

  1. Utilizzare un tag di struttura, come già mostrato in varie altre risposte.

    typedef struct pr_PendingResponseItem 
    { 
        // some fields required for processing... 
        int (*doAction)(struct pr_PendingResponseItem *pr); 
    } pr_PendingResponseItem; 
    
    typedef struct LinkedItem 
    { 
        struct LinkedItem *prev; 
        struct LinkedItem *next; 
        void * data; 
    } LinkedItem; 
    
  2. Usa typedef invia un nome a un tipo di struttura incompleta e utilizzare il typedef nella definizione della struttura.

    typedef struct pr_PendingResponseItem pr_PendingResponseItem; 
    struct pr_PendingResponseItem 
    { 
        // some fields required for processing... 
        int (*doAction)(pr_PendingResponseItem *pr); 
    }; 
    
    typedef struct LinkedItem LinkedItem; 
    struct LinkedItem 
    { 
        LinkedItem *prev; 
        LinkedItem *next; 
        void * data; 
    }; 
    

Si noti che le variabili di struttura sono in uno spazio diverso dai typedef nomi, quindi non c'è alcuna necessità di utilizzare nomi diversi per il tag typedef e la struttura. Si noti inoltre che in C++ lo typedef non sarebbe necessario.

+1

Questa è l'unica risposta che in realtà ha identificato che è possibile inoltrare dichiarare il 'typedef'. –

Problemi correlati