IOCP 无法在 x64 平台上运行

Posted

技术标签:

【中文标题】IOCP 无法在 x64 平台上运行【英文标题】:IOCP can not run in x64 platform 【发布时间】:2015-08-24 12:23:47 【问题描述】:

我在 x64 平台使用 IOCP 时遇到问题。

当我在 win32 平台上编译我的代码时,它运行良好。但是当我将其更改为 x64 平台时,功能

GetQueuedCompletionStatus(CompletionPort, &BytesTransferred,(PULONG_PTR)&PerHandleData, (LPOVERLAPPED*)&IpOverlapped, INFINITE)

返回 true 而不将值传递给 PerHandleData。

PerHandleData 定义为:

typedef struct

SOCKET socket;
SOCKADDR_STORAGE ClientAddr;
PER_HANDLE_DATA,*LPPER_HANDLE_DATA;
LPPER_HANDLE_DATA PerHandleData;

这意味着,即使函数 GetQueuedCompletionStatus() 似乎没有错误,struct PerHandleData 也无法读取内存:socket 无法读取内存,ClientAddr 也是如此。没有价值观。

所以当它运行到函数WSARecv(PerHandleData->socket, &(PerIoData->databuff), 1, &RecvBytes, &Flags, &(PerIoData->overlapped), NULL);应用程序将因内存错误而停止。

谁能告诉我怎么处理?

【问题讨论】:

我们需要查看更多代码。 【参考方案1】:

我刚遇到同样的问题,问题是在 32 位时,我只是将完成密钥转换为 DWORD 并将其传递给 CreateIoCompletionPort 调用。在 64 位应用程序中,它仍然可以构建,只是一个编译器警告。更改代码并转换为ULONG_PTR 将解决问题。更复杂的警告只是说明原因:data truncated。当点地址大于 32 位时,GetQueuedCompletionStatus 会得到截断的地址,只有 32 位。

【讨论】:

【参考方案2】:

CreateIoCompletionPort 的文档告诉我们密钥的来源;在将它与GetQueuedCompletionStatus 一起使用之前,您需要将密钥传递给CreateIoCompletionPort

CreateIoCompletionPort 的文档还指出,每个文件句柄 的密钥应该是唯一的。 (不仅仅是每个文件)。

因此,由于我们没有实际代码,因此这两个要求是主要的嫌疑人。一个特殊的挑战可能是完成键的间接级别。您将密钥传递给 CreateIoCompletionPort 并将 指针 传递给 GetQueuedCompletionStatus 的密钥(因此它将把密钥放在指向的位置 - 这是一个 OUT 参数)。而那个键可能是一个指针本身。

【讨论】:

以上是关于IOCP 无法在 x64 平台上运行的主要内容,如果未能解决你的问题,请参考以下文章