Для правильной работы GetIoCompletionPort
необходимо указать ненулевой указатель на ULONG_PTR
, чтобы записать значение ключа в:
ULONG_PTR key;
GetQueuedCompletionStatus(
completion_port,
&numBytes,
&key,
&po,
INFINITE
);
Чтобы успешно использовать GetOverlappedResult
, я считаю, что вам нужно указать дескриптор события в структуре OVERLAPPED
(настоятельно рекомендуется в любом случае):
o.hEvent = CreateEvent(NULL, FALSE, TRUE, NULL);
Называть двоих подряд такими, какими вы были, на самом деле мало что дает - они оба говорят вам об одних и тех же вещах. Хотя, если вы вызовете оба по очереди, вам нужно изменить Событие на ручной сброс, изменив третий параметр на CreateEvent
на ИСТИНА. Я думаю, что вы просто пытались оба, чтобы увидеть, если вы могли бы получить один на работу. Учитывая все обстоятельства, я бы, вероятно, просто использовал GetQueuedCompletionStatus
и оставил это на этом. Конечно, вы обычно делаете больше, чем звоните один раз и выходите. Вы обычно вызываете его в цикле, обрабатывая текущий прочитанный буфер, затем вызываете ReadFile
снова, чтобы прочитать другой буфер информации, что-то вроде этого:
DWORD numBytes;
LPOVERLAPPED po;
while (GetQueuedCompletionStatus(completion_port, &numBytes, &key, &po, INFINITE)) {
std::cout << "\rRead: " << numBytes; // just to show it's set correctly.
process(buffer);
po->offset += sizeof(buffer);
ReadFile(file, buffer, sizeof(buffer), NULL, po);
}
По крайней мере, в быстром тесте на моей машине это показало количество прочитанных байт правильно (sizeof(buffer)
до последнего пакета, затем оставшийся размер файла).