关于在 winsock 的 addrinfo 结构中使用智能指针的问题
Questions about using smart pointers with winsock's addrinfo struct
我正在尝试使用 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*)
作为函数类型是行不通的,并且会吐出一堆我无法理解的难以理解的模板错误。
__stdcall
是一个calling convention,它控制函数参数的传递方式,调用堆栈的清理方式等。您的int*
示例没有指定调用约定它的删除器,因此使用编译器的默认调用约定(通常是 __cdecl
)。但是 API 函数已经定义了用于互操作目的的调用约定,因此您必须使用正确的约定。几乎所有 Win32 APIs(除了少数例外)都使用 __stdcall
调用约定。
与其对删除器的类型进行硬编码,不如使用 decltype
并让编译器为您推断类型会更容易:
addrinfo *addr;
getaddrinfo(..., &addr);
unique_ptr<addrinfo, decltype(&::freeaddrinfo)> addrPtr(addr, &::freeaddrinfo);
我正在尝试使用 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*)
作为函数类型是行不通的,并且会吐出一堆我无法理解的难以理解的模板错误。
__stdcall
是一个calling convention,它控制函数参数的传递方式,调用堆栈的清理方式等。您的int*
示例没有指定调用约定它的删除器,因此使用编译器的默认调用约定(通常是 __cdecl
)。但是 API 函数已经定义了用于互操作目的的调用约定,因此您必须使用正确的约定。几乎所有 Win32 APIs(除了少数例外)都使用 __stdcall
调用约定。
与其对删除器的类型进行硬编码,不如使用 decltype
并让编译器为您推断类型会更容易:
addrinfo *addr;
getaddrinfo(..., &addr);
unique_ptr<addrinfo, decltype(&::freeaddrinfo)> addrPtr(addr, &::freeaddrinfo);