Использование @ для имен переменных, которые являются ключевыми словами.
var @object = new object();
var @string = "";
var @if = IpsoFacto();
GetQueuedCompletionStatus
возвращает две вещи: структуру OVERLAPPED
и ключ завершения. Ключ завершения представляет информацию для каждого устройства, а структура OVERLAPPED
представляет информацию для каждого вызова. Ключ завершения должен соответствовать тому, что было указано в вызове CreateIoCompletionPort
. Как правило, в качестве ключа завершения используется указатель на структуру, содержащую информацию о соединении.
Похоже, что вы ничего не делаете с ключ завершения
, возвращенный GetQueuedCompletionStatus
.
Я полагаю, вы хотите:
if completionKey != acceptKey:
Cleanup()
...
редактировать:
Проблема в том, как я передаю ключи завершения. Аргумент ключа завершения является указателем, но он передает обратно указатель, а не указанное значение - по крайней мере, это немного сбивает меня с толку.
Также ключ завершения, переданный для принятого перекрывающегося пакета соединения, является ключом прослушивающего сокета, а не принятая розетка.
What I ' В повседневной практике я обнаружил, что лучше всего просто сосредоточиться на результате OVERLAPPED
, так как он не изменится. Один из способов эффективного использования этого результата - это иметь что-то вроде следующего:
struct CompletionHandler
{
OVERLAPPED dummy_ovl;
/* Stuff that actually means something to you here */
};
Когда вы публикуете что-то в IOCP (через вызов ввода-вывода или просто сообщение через Win32 API) вы сначала создаете объект CompletionHandler
, который будете использовать для отслеживания вызова, и приводите адрес этого объекта к ] ПЕРЕСЕЧЕНИЕ *
.
CompletionHander my_handler;
// Fill in whatever you need to in my_handler
// Don't forget to keep the original my_handler!
// I/O call goes here, and for OVERLAPPED* give: (OVERLAPPED*)&my_handler
Таким образом, когда вы получите результат OVERLAPPED
, все, что вам нужно сделать, это вернуть его в CompletionHandler
и вуаля! У вас есть исходный контекст вашего звонка.
OVERLAPPED* from_queued_completion_status;
// Actually get a value into from_queued_completion_status
CompletionHandler* handler_for_this_completion = (CompletionHandler*)from_queued_completion_status;
// Have fun!
Для получения дополнительных сведений в реальных условиях ознакомьтесь с реализацией ASIO для Windows в Boost ( ver 1.42, заголовок здесь ). Есть некоторые детали, такие как проверка указателя OVERLAPPED
, который вы получаете из GetQueuedCompletionStatus
, но, опять же, посмотрите ссылку, чтобы найти хороший способ реализации.
Ключ завершения не является указателем - это число типов ULONG_PTR, что просто означает "целое число размером указателя", поэтому оно составляет 32 бита на x86 и 64 бита на x64. Typename сбивает с толку, но когда win32 typenames ссылаются на указатель, они делают это, имея P в начале имени, а не в конце.