有关在Winsock的addrinfo结构中使用智能指针的问题

时间:2019-01-25 18:43:57

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

我正在尝试使用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*)作为函数类型是行不通的,并且会吐出一堆我不理解的无法理解的模板错误。

1 个答案:

答案 0 :(得分:1)

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

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

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