解释 getaddrinfo( ) 的参数
Posted
技术标签:
【中文标题】解释 getaddrinfo( ) 的参数【英文标题】:Explain parameters of getaddrinfo( ) 【发布时间】:2015-10-01 19:31:56 【问题描述】:我不明白的是**res
双指针,在手册页中它指出:
hints 参数指向一个 addrinfo 结构,该结构指定 选择返回的套接字地址结构的标准 res 指向的列表。
我看到*hints
是一个指向addrinfo
结构的指针,但是**res
如何返回套接字地址结构?
Specification:
int getaddrinfo(const char *node, const char *service,
const struct addrinfo *hints,
struct addrinfo **res);
struct addrinfo
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
socklen_t ai_addrlen;
struct sockaddr *ai_addr;
char *ai_canonname;
struct addrinfo *ai_next;
;
【问题讨论】:
看看文档,在页面的最末尾man7.org/linux/man-pages/man3/getaddrinfo.3.html - 敢于克服 TL;DR 【参考方案1】:使用指向指针的指针是一种常见模式,其中函数使用“out”参数返回已分配内存的地址。这样做是为了让调用者不必预先分配,有时是未知的大小。
典型的用法是通过地址操作符 (&
) 使用指针类型,如下所示:
struct addrinfo *result;
getaddrinfo("foo", "baz", NULL, &result);
然后,result
,这是一个未初始化的变量正在指向一个真实的内存地址,稍后在代码中预计它将被调用者释放:
freeaddrinfo(result);
【讨论】:
C 没有引用,并且一元&
运算符在 C 上下文中通常不称为“引用”运算符。事实上,即使在 C++ 中,我也不认为使用 &
来标记引用类型符合操作的条件。该标准将一元 &
称为“地址”运算符,在其他地方我经常看到拼写为“地址”。但是,否则,您的解释很好。
@JohnBollinger A. 你是对的。 B. 我什至没有注意到它是 C 而不是 C++ :-)
我在下面发布的相同评论,为什么它使用**
double 而不是*
single,addrinfo
结构不是指针,所以他们为什么在规范中使用 double。
@JordanDavis 该变量被定义为一个指针(1 *
),因此它指向一个带有结构值的内存地址。地址运算符获取变量的地址并将其传递给函数,以便它 (getaddrinfo
) 可以“改变”变量,并设置它指向的地址。这很像你有一个函数:void f(int *i) ;
,你把它和int i; f(&i);
一起使用。
我明白了……再说一遍,为什么它使用**
而不是*
single【参考方案2】:
res
是一个指针,指向您希望存储结果(本身是指针形式)的位置。因此,您可以执行以下操作:
struct addrinfo hints = .ai_socktype = SOCK_STREAM ;
struct addrinfo *ai;
int err_code = getaddrinfo(hostname, service, &hints, &ai));
之后,如果没有错误,ai
已更新为指向您的结果(addrinfo
结构的链表的第一个元素)。
【讨论】:
为什么**
double,即使在您的示例中,您使用*
单,甚至在“客户端程序”man7.org/linux/man-pages/man3/getaddrinfo.3.html 下的手册页中,它也使用struct addrinfo *result, *rp;
,这是单。我的意思是 struct addrinfo
不是指针,所以我为什么要声明 **
双精度,你知道的。
@JordanDavis:res 参数是指向存储结果的位置的指针。结果本身具有指针类型。因此,参数是指向指针的指针。这并不意味着结果对象(在我的示例代码中为ai
)应该是双指针类型。相反,您传递它的地址,&ai
,其类型是“指向ai
类型的指针”,因此指向指向struct addrinfo
的指针。 以上是关于解释 getaddrinfo( ) 的参数的主要内容,如果未能解决你的问题,请参考以下文章
getaddrinfo with fist NULL参数给出第一个IPv4而不是IPv6