2015-06-09 84 views
1
void Link::keepalive(bool enable){ 
    int opt = enable? 1 : 0; 
    ::setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&opt, sizeof(opt)); 
} 

我不断看到这样特别是当它涉及到插座和网络操作在一些比较低级的C函数下面的代码。为什么被引用的int被转换为void指针?

我来自一个python背景,并且我确定四处寻找好的解释,说明(void *)&opt正在做什么,但还没有找到一个好的解释。

我得到的引用仅仅是有限制的指针。

+1

'(void *)'被称为''cast'',它基本上表明指针('opt'变量的地址)应该被看作是指向'void'数据类型的指针。在大多数情况下,在'C'中,这不是必需的或冗余的。 –

+1

在C++中,你应该使用'reinterpret_cast'。 – 101010

+1

'&opt'不是引用,并且在C/C++中不需要强制转换。 – yngccc

回答

3

setsockopt

int setsockopt(int socket, int level, int option_name, 
    const void *option_value, socklen_t option_len); 

倒数第二个参数签名应该为void *类型。为了使&opt类型void *它被捕获到该类型。

还要注意的是&optopt对象的地址。它没有参考。

0

这的确是相当存在于首位,因为setsockopt的()是支持吨的不同选项(SO_KEEPALIVE只是其中之一)一个烂摊子。

  • 要启用传递任何参数(包括未来的扩展),他们已经说setsockopt的()将接受的指针参数,其中参数类型是任何指针(和被隐含由下式定义option_name参数,在本例中为SO_KEEPALIVE)。

    • 这确保setsockopt的()的原型仍然是SO_的所有未来值*选项
  • 用C

    “任何指针” 被写为 “空隙*”

  • 相同

    & opt是 “指针选择”(或 “选择的地址”)

  • 如 “选择” int类型, “&选择” int类型*,因此将它转换到void *,有一个“显式转换”(无效*)&选择在你的代码

    • 然而,在大多数情况下是没有必要的,因为转换为void *是隐式的,就这么简单“&选择”应该做
  • 这种挂羊头卖狗肉的,而用C API的常见的,通常是在C++气馁,所以不要把它作为“如何编写C++程序”的一个例子

0

看看MSDN文档为setsockopt功能,特别是备注部分:

有两种类型的插座选项:布尔选项,启用或禁用的特征或行为,需要一个整数值或结构的选项。要启用布尔选项,optval参数指向一个非零整数。要禁用选项optval指向一个等于零的整数。对于布尔选项,optlen参数应该等于sizeof(int)。 对于其他选项,optval指向包含选项所需值的整数或结构,optlen是整数或结构的长度。

它是用C的API通常的做法是通过函数的参数,可以是不同的类型/长度的作为最一般的指针类型(void *)指向它们在存储器地址。

&opt(int *)的指针/地址返回到opt,因此需要将其转换为(void *)。在编写C++时,更喜欢使用explicit type conversions

+2

微软并不是唯一实现Berkeley套接字的系统,而且尤其是setsockopt(),因此命名MSDN的“官方文档”是一个很长的镜头。 –

相关问题