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 平台上运行的主要内容,如果未能解决你的问题,请参考以下文章

VS 本地调试 x64 平台 “Visual Studio Remote Debugging Monitor 已停止工作” 问题解决

国产化之x64平台安装银河麒麟操作系统

DIOCP DIOCP常见问题。

Silverlight OOB或WebHosted可以在x64平台下构建吗?

如何修复“生成器 MinGW Makefiles 不支持平台规范,但指定了 x64 平台?

在“任何 CPU”.NET 程序集上强制 x86 CLR