2012-03-13 2 views
1

나는 IOCP로 게임을하고 있습니다. 비동기가 주 스레드의 파일에서 데이터를 읽는 간단한 응용 프로그램을 작성하려고합니다. 그러나 내가 오류 (ERROR_INVALID_PARAMETER) ReadFileEx 함수를 받고 있어요,하지만 난 그것을하고있어 보인다. 내가 도대체 ​​뭘 잘못하고있는 겁니까? 여기 내 예입니다IOCP 및 ReadFileEx 사용

#include "stdafx.h" 
#include <windows.h> 
#include <assert.h> 
#include <stdint.h> 

VOID CALLBACK ReadCb(DWORD dwErrorCode,DWORD dwNumberOfBytesTransfered,LPOVERLAPPED lpOverlapped) 
{ 
    fprintf(stderr,"i was here\n"); 
} 


int _tmain(int argc, _TCHAR* argv[]) 
{ 
    HANDLE main_io,file_i; 
    HANDLE file_handle; 
    DWORD bytes_recvd; 
    ULONG_PTR data = 0; 
    OVERLAPPED overlapped; 
    LPOVERLAPPED poverlapped = &overlapped; 
    uint8_t read_data[1024]; 
    DWORD err; 

    main_io = CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0); 
    assert(main_io != NULL); 

    file_handle = CreateFile(L"test.txt",GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED, NULL); 
    assert(file_handle != INVALID_HANDLE_VALUE); 

    file_i = CreateIoCompletionPort(file_handle,main_io,data,0); 
    assert(file_i != NULL); 

    memset(&overlapped,0,sizeof(OVERLAPPED)); 

    err = ReadFileEx(file_handle,(LPVOID)read_data,1024,&overlapped,ReadCb); 
    fprintf(stderr,"err %d\n",GetLastError()); 
    assert(err != 0); 

    assert(GetQueuedCompletionStatus(file_i,&bytes_recvd,&data,&poverlapped,INFINITE)); 

    CloseHandle(main_io); 
    return 0; 
} 
+0

OVERLAPPED overlapped = {};를 사용할 수 있습니다. memset (& overlapped, 0, sizeof (OVERLAPPED)) 대신; – evpo

답변

0

마틴 말했듯이 특별한 경우의 비트가 있지만, 첫째, 당신이 ReadFileEx()에서 성공 반환에 대한 GetLastError()를 호출해서는 안 마틴은 자신의 가정에 대한 잘못된

const BOOL result = ReadFileEx(...); 

const DWORD lastError = GetLastError(); 

if (lastError != ERROR_SUCCESS) 
{ 
    fprintf(stderr, "err %d\n", lastError); 
} 

주를 처리하여 오류를 수정 ...부터 MSDN docs :

ReadFileEx를 사용하는 경우는 GetLastError를 확인해야합니다 심지어 기능 "성공"가있는 조건을 확인하는 "성공"을 반환 할 때 그러나 당신이 알기를 원하는 약간의 결과가 있습니다. 예제의 경우 ReadFileEx를 호출 할 때 버퍼 오버플로는 TRUE를 반환하고 은 GetLastError가 ERROR_MORE_DATA로 오버플로를보고합니다. 함수 호출이 성공하고 경고 조건이없는 경우 GetLastError는 ERROR_SUCCESS를 반환합니다.

하지만 그건 문제가 해결되지 않는, 그냥

문제는 ReadFileEx()가 완료 루틴을 사용하여 읽기 비동기 파일을 수행하고 당신이해야 할 노력하고 있다는 것입니다 ... 당신의 예제 코드가 더 정확합니다 I/O 완료 포트를 사용한 비동기 파일 읽기. 이를 위해서는 ReadFile()을 사용해야합니다. 완료 루틴은 불쾌한 조금 ...

그래서를 왜 내가 IOCP가 취할 수있는 더 나은 경로하다고 생각하는 이유에 대한 this answer를 참조하고, 단순히 ReadFile() 전화에 ReadFileEx() 전화를 변경하고 문제가 사라질 것이며, 코드 것 읽기가 완료되면 IOCP에 완료를 게시하십시오 ...

ReadFile(file_handle,(LPVOID)read_data,1024,&overlapped); 

그리고 끝났습니다.

+0

고마워요, 그게 전부입니다! 어제 나 자신을 찾았지만 나는이 사이트의 새로운 사용자이기 때문에 나의 질문에 답할 수 없었다! – user1266334

+0

오 예. 어떻게 든, 나는 'ReadFileEx'를 보았지만 'WSARecv'를 읽었습니다. (( –

1

'함수가 성공적으로 실행 된 경우 반환 값이 0이 아닌'- 0이 아닌 리턴을 위해 GetLastError()를 호출하지 마십시오! 어설 션 위반 예외가 발생하면 GetLastError에 도달하지 않도록 어설 션 검사 후 GetLastError 행을 이동합니다.