有关将智能指针与 Winsock 的 addrinfo 结构一起使用的问题



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

所以我对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是一种调用约定,它控制如何传递函数参数,如何清理调用堆栈等。您的int*示例没有为其删除程序指定调用约定,因此使用编译器的默认调用约定(通常为 __cdecl )。但是 API 函数已为互操作目的定义了调用约定,因此您必须使用正确的约定。几乎所有 Win32 API(少数例外)都使用 __stdcall 调用约定。

与其对删除程序的类型进行硬编码,不如使用decltype,让编译器为您推断类型:

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

相关内容

  • 没有找到相关文章

最新更新