在 Win64 下将 SOCKET 转换为 int 是否安全? [英] Is it safe to cast SOCKET to int under Win64?

查看:38
本文介绍了在 Win64 下将 SOCKET 转换为 int 是否安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理 POSIX C++ 程序的 Windows 端口.

问题是像 accept() 或 bind() 这样的标准 POSIX 函数需要一个‘int’作为第一个参数,而它的 WinSock 对应函数使用‘SOCKET’.
编译为 32 位时一切正常,因为两者都是 32 位,但在 Win64 下 SOCKET 是 64 位,int 仍然是 32 位,它会生成很多编译器警告,如下所示:

警告 C4244:=":从SOCKET"到int"的转换,可能会丢失数据

我试图通过使用 typedef 来解决这个问题:

<预><代码>#ifdef _WIN32typedef SOCKET sock_t;#别的typedef int sock_t;#万一

并在适当的地方用 sock_t 替换‘int’.

这很好,直到我到达调用 OpenSSL API 的代码的一部分.
事实证明,即使在 Win64 上,OpenSSL 也使用整数作为套接字.这看起来真的很奇怪,所以我开始寻找答案,但我唯一找到的是 openssl-dev 邮件列表上的一篇旧帖子,其中引用了 e_os.h 的评论:

<预><代码>/** 即使 sizeof(SOCKET) 是 8,也可以安全地将其转换为 int,因为* 该值构成每个进程表中有限大小的索引* 而不是真正的指针.*/

所以我的问题是:
将 SOCKET 转换为 int 真的安全吗?

我想看一些证明 SOCKET 值不能大于 2^32 的文档.

提前致谢!
赖克

解决方案

这个 post 似乎是在重复关于 内核对象 msdn:

<块引用>

内核对象句柄是特定于进程的.也就是说,进程必须创建对象或打开现有对象才能获得内核对象句柄.内核句柄的每个进程限制是 2^24.

该线程继续引用 Russinovich 和 Solomon 的 Windows Internals 作为高位为零的来源.

I’m working on a Windows port of a POSIX C++ program.

The problem is that standard POSIX functions like accept() or bind() expect an ‘int’ as the first parameter while its WinSock counterparts use ‘SOCKET’.
When compiled for 32-bit everything is fine, because both are 32bit, but under Win64 SOCKET is 64 bit and int remains 32 bit and it generates a lot of compiler warning like this:

warning C4244: '=' : conversion from 'SOCKET' to 'int', possible loss of data

I tried to work around the issue by using a typedef:


#ifdef _WIN32
 typedef SOCKET sock_t;
#else
 typedef int sock_t;
#endif

and replacing ‘int’s with sock_t at the appropriate places.

This was fine until I reached a part of the code which calls OpenSSL APIs.
As it turned out OpenSSL uses ints for sockets even on Win64. That seemed really strange, so I started searching for an answer, but the only thing I found was an old post on the openssl-dev mailing list which refered to a comment e_os.h:


/*
 * Even though sizeof(SOCKET) is 8, it's safe to cast it to int, because
 * the value constitutes an index in per-process table of limited size
 * and not a real pointer.
 */

So my question is:
is it really safe to cast SOCKET to int?

I’d like to see some kind of documentation which proves that values for SOCKET can't be larger than 2^32.

Thanks in advance!
Ryck

解决方案

This post seems by the to be repeating the information on kernel objects at msdn:

Kernel object handles are process specific. That is, a process must either create the object or open an existing object to obtain a kernel object handle. The per-process limit on kernel handles is 2^24.

The thread goes on to cite Windows Internals by Russinovich and Solomon as a source for the high bits being zero.

这篇关于在 Win64 下将 SOCKET 转换为 int 是否安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆