2012-11-11 100 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>

这是程序员的最佳实践。