2012-11-11 315 views
6

我對這種說法,其被定義爲參數傳遞給函數

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

,並稱爲

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

我無法解釋什麼struct sockaddr_in *這裏指的功能相混淆。

這項工作:bind (sd, &addr, length);

+0

電話會引發警告。 – alk

+0

好,那麼'struct sockaddr_in *'如何避免它? 我以前從來沒有見過這樣的論點,所以我不知道它到底在做什麼。 – pushgr8

+1

'struct sockaddr_in *'引發警告。它應該是'struct sockaddr *'。 – alk

回答

3

它應該被稱爲是這樣的:

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

至於爲什麼,這是做polymorphism的C-方式,如果你看看這些結構的定義:

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 
}; 

他們都共享相同的第一個成員sa_family當您將指針傳遞給bind()時,您首先將其指向struct sockaddr *並在函數內使用sa_family來確定你傳遞了哪個結構並將其轉換回正確的結構,而不是每個結構都具有一個函數,而只有一個函數接受sockaddr*

另一種方式看,從OOP的角度看,設想sockaddr是基類爲sockaddr_in和,和指針傳遞到sockaddr類似於鑄造到基類型和調用的通用函數。希望這更清楚。

+0

這是描述性的,理解這裏需要類型轉換,謝謝。 '人綁定'只是舉例,但我找不到結構定義。 – pushgr8

+0

@ pushgr8歡迎您:) – iabdalkader

2

除了void指針外,指針到T到指向U的指針的轉換應該是明確的。

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

這取決於addr是什麼。

如果那麼你需要強制轉換它,其他明智的,你會得到警告隱含類型轉換,從<type of addr>const struct sockaddr*

要查看任何程序編譯由編譯器提供的所有警告消息這不是同一結構的地址。 開始使用這個(編譯器警告gcc):

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

這是程序員的最佳實踐。