【问题标题】:Questions about using smart pointers with winsock's addrinfo struct关于在 winsock 的 addrinfo 结构中使用智能指针的问题
【发布时间】:2019-01-26 03:26:09
【问题描述】:

我正在尝试使用 unique_ptr 处理 winsock 的 addrinfo 指针。 在做了一些研究之后,我发现了一个没有得到很好解释的答案,所以现在我很困惑。 (我说的答案:Smart pointers with addrinfo struct

所以我对unique_ptr的一般理解说语法如下: unique_ptr<type of handled data, type of function deleting the data>(pointer, deleter function pointer);.

一个基本的例子是:

void deleteInt(int* ptr){...}

int* ptr = new int;
unique_ptr(int, void(*)(int*)>(ptr, deleteInt);

请注意函数类型如何没有指定名称,而只是有(*)

现在,最后,谈谈我的问题: 在我上面提到的答案中,代码做了一些奇怪的事情。 不是unique_ptr<addrinfo, void(*)(addrinfo*)>...,而是unique_ptr<addrinfo, void(__stdcall*)(addrinfo*)>...,似乎没有人质疑它。怎么会这样?它如何改变函数的类型?什么是__stdcall?为什么它甚至可以工作,因为T (name*)() 甚至不是有效的语法?不用说,简单地将void(*)(addrinfo*) 作为函数类型是行不通的,并且会吐出一堆我不理解的难以理解的模板错误。

【问题讨论】:

    标签: c++ function-pointers smart-pointers winsock2


    【解决方案1】:

    __stdcall 是一个calling convention,它控制函数参数如何传递,调用堆栈如何清理等。你的int* 示例没有为其删除器指定调用约定,因此编译器的默认调用使用约定(通常是__cdecl)。但 API 函数已为互操作目的定义了调用约定,因此您必须使用正确的约定。几乎所有 Win32 API(除了少数例外)都使用 __stdcall 调用约定。

    与其对删除器的类型进行硬编码,不如使用decltype 并让编译器为您推断类型会更容易:

    addrinfo *addr;
    getaddrinfo(..., &addr);
    unique_ptr<addrinfo, decltype(&::freeaddrinfo)> addrPtr(addr, &::freeaddrinfo);
    

    【讨论】:

    • 感谢您提供的信息丰富的答案,我不知道这样的事情甚至存在。您能否详细说明将 decltype 与&amp;:: 一起使用意味着什么?我从未见过它以这种方式使用。
    • @Habitate &amp; 是地址运算符,:: 是范围运算符。该代码获取位于全局命名空间中的freeaddrinfo 函数的地址。
    • 感谢提醒,我对&amp; 运算符有点困惑,因为我认为使用简单的函数名与传递指针相同。 decltype 似乎并非如此。
    猜你喜欢
    • 2014-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多