2012-11-11 17 views
6

Sono confuso da questo argomento per la funzione che è definita comeargomento alla funzione

int bind(int s, const struct sockaddr *name, int namelen) 

e chiamato come

bind(sd, (struct sockaddr_in *) &addr, length); 

Sono in grado di interpretare ciò che significa struct sockaddr_in * qui.

Questo lavoro: bind (sd, &addr, length);?

+0

La chiamata provocherebbe un avviso. – alk

+0

ok allora come 'struct sockaddr_in *' lo sta evitando? Non ho mai accettato un argomento del genere, quindi non capisco esattamente cosa stia facendo. – pushgr8

+1

'struct sockaddr_in *' provoca l'avviso. Dovrebbe essere 'struct sockaddr *'. – alk

risposta

3

dovrebbe essere chiamato in questo modo:

bind (sd, (struct sockaddr *) &addr, length); 

Per quanto riguarda il motivo per cui, questo è il modo C di fare polymorphism, se si guardano le definizioni di tali strutture:

struct sockaddr { 
    unsigned short sa_family; // address family, AF_xxx 
    char    sa_data[14]; // 14 bytes of protocol address 
}; 

// IPv4 AF_INET sockets: 
struct sockaddr_in { 
    short   sin_family; // e.g. AF_INET, AF_INET6 
    unsigned short sin_port;  // e.g. htons(3490) 
    struct in_addr sin_addr;  // see struct in_addr, below 
    char    sin_zero[8]; // zero this if you want to 
}; 

// IPv6 AF_INET6 sockets: 
struct sockaddr_in6 { 
    u_int16_t  sin6_family; // address family, AF_INET6 
    u_int16_t  sin6_port;  // port number, Network Byte Order 
    u_int32_t  sin6_flowinfo; // IPv6 flow information 
    struct in6_addr sin6_addr;  // IPv6 address 
    u_int32_t  sin6_scope_id; // Scope ID 
}; 

Tutti condividere lo stesso primo membro, sa_family quando si passa un puntatore a una di quelle strutture a bind() per la prima volta trasmesso a struct sockaddr * e all'interno della funzione, sa_family viene utilizzato per determinare quale struttura hai passato e ricondotta a quella giusta, invece di avere una funzione per ogni struttura hai una funzione che accetta sockaddr*.

Un altro modo di vedere le cose, dal punto di vista OOP, immaginare che sockaddr è la classe base per sockaddr_in e , e passando un puntatore a sockaddr è simile a lanciare al tipo di base e chiamando una funzione generica. Spero che questo lo renda più chiaro.

+0

questo era descrittivo, capito la necessità di typecasting qui, grazie. 'man bind' ha presentato solo un esempio ma non sono riuscito a trovare la definizione della struttura. – pushgr8

+0

@ pushgr8 sei il benvenuto :) – iabdalkader

2

Tranne che con i puntatori void, la conversione da un puntatore a T in un puntatore su U deve essere esplicita.

bind (sd, (struct sockaddr *) &addr, length); 
1

Dipende da cosa è addr.

Se non è l'indirizzo della stessa struct allora avete bisogno di typecast esso, l'altro saggio si otterrà avvertendo che typecast implicita da <type of addr> a const struct sockaddr*

Per visualizzare i tutti i messaggi di avvertimento fornite dal compilatore in compilazione di qualsiasi programma . iniziare a utilizzare questo (per il compilatore gcc avvertimenti):

gcc -Wall <test.c> -o <test>

E 'la migliore pratica per i programmatori.

Problemi correlati