2010-11-13 86 views
1

我有一個Wiimote的READFILE對HID有時會錯誤的價值觀

handle = CreateFile(didetail->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); 
if(handle != INVALID_HANDLE_VALUE) { 
    opened = true; 
    readReportEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 
    memset(&readOverlapped, 0, sizeof(readOverlapped)); 
    readOverlapped.hEvent  = readReportEvent; 
    readOverlapped.Offset  = 0; 
    readOverlapped.OffsetHigh = 0; 

    writeReportEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 
    memset(&writeOverlapped, 0, sizeof(writeOverlapped)); 
    writeOverlapped.hEvent = readReportEvent; 
    writeOverlapped.Offset = 0; 
    writeOverlapped.OffsetHigh = 0; 
} 

我有一個線程總是讀這個把手新消息的連接:

while(opened && readThreadNextStatus){ 
    memset (readBuff, 0, 22); 
    BYTE* ptrbuff = new BYTE[22]; 
    int readfile = ReadFile(handle, readBuff, reportLength, NULL, &readOverlapped); 
    if(readfile == 0 && GetLastError() == ERROR_IO_PENDING){ 
     DWORD waitError; 
     do 
     { 
      waitError = WaitForSingleObject(readReportEvent, timeout); 
     } while (waitError == WAIT_TIMEOUT && opened && readThreadNextStatus); 

     if(opened && readThreadNextStatus){ 
      DWORD read = 0; 
      if(waitError == WAIT_OBJECT_0){ 
       GetOverlappedResult(handle, &readOverlapped, &read, TRUE); 
      } 
      ResetEvent(readReportEvent); 
      memcpy(ptrbuff, readBuff, 22); 

     cout << "Read: "; 
     coutHex(ptrbuff); 
     } 
    } 
} 

我寫功能:

if(opened){ 
    if(!WriteFile(handle, buff, reportLength, NULL, &writeOverlapped)){ 
     if(GetLastError() != ERROR_IO_PENDING){ 
      close(); 
     } 
    } 
    WaitForSingleObject(writeReportEvent, timeout); 
    DWORD write = 0; 
    GetOverlappedResult(handle, &writeOverlapped, &write, TRUE); 
    ResetEvent(writeReportEvent); 
} 
cout << "Write: "; 
coutHex(buff); 

控制檯輸出:

Connection established 
Write: 15- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 
Read: 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 
Read: 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 
Write: 15- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 
Read: 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 
Write: 15- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 
Read: 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 
Read: 20- 0- 0-10- 0- 0-49-ff-ff-ff-ff-ff-ff-ff-ff-ff-ff-ff-ff-ff-ff-ff- 
Write: 15- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 
Read: 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 
Write: 15- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0 
Read: 0- 0- 
0- 0- 
- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 

coutHex總是以十六進制格式打印接收到的數據。有時候我會得到正確的數據,但有時候數組只能加載00 00 00 00 00 00 00 00 00 00

我經歷過,當我寫作的時候,我總是得到一份報告,其中只包含00,這在我的寫入功能在控制檯輸出上寫入之前出現。

我很絕望,所以我嘗試了這一點:

do 
      { 
       waitError = WaitForSingleObject(readReportEvent, timeout); 
       Sleep(500); 
      } while (waitError == WAIT_TIMEOUT && opened && readThreadNextStatus); 

我不知道爲什麼,但現在它的工作原理(不細,因爲它有500ms的延遲)。

您認爲如何?也許ReadFile和WriteFile不能同時工作?

這是什麼原因造成的?我錯過了什麼?

回答

2

還有一些其他問題:

  • 創建手動重置事件(CreateEvent(NULL,TRUE,FALSE,NULL)),而不是自動重置事件(CreateEvent(NULL,FALSE,FALSE,NULL)) 。

  • 檢查ReadFile是否返回FALSE,GetLastError的值是ERROR_IO_PENDING,在這種情況下等待事件(WaitForSingleObject)。

  • 如果WaitForSingleObject返回WAIT_OBJECT_0,則調用GetOverlappedResult。

    如果您使用GetOverlappedResult,則不需要傳遞lpNumberOfBytesRead,因爲此函數也會返回此值。

+0

我已經編輯我原來的問題與您的想法,請檢查代碼。這沒有解決問題。 – 2010-11-13 22:13:33

+1

在GetOverlappedResult之後放置ResetEvent(ReportEvent),因爲此函數返回設置的事件(您正在使用TRUE作爲bWait參數)。您不需要在GetOverlappedResul之前放置ResetEvent(ReportEvent),因爲此函數會重置事件。 – 2010-11-13 23:24:17

+0

謝謝,我已經改變了它,但同樣的問題存在:S – 2010-11-13 23:30:56

1

您不應該在超時後重複ReadFile,而是再次重複WaitForSingleObject。您仍然有待閱讀。窮人的循環(你應該完善它,使用戶可以中止它):

DWORD waitError; 
do 
{ 
    waitError = WaitForSingleObject(ReportEvent, timeout); 
} 
while (waitError == WAIT_TIMEOUT); 
+0

感謝您的回答,我將它添加到了我的代碼中。對於第一次運行,我認爲它解決了這個問題,但經過一些測試後,我又經歷了這個問題。我已經添加了關於數據包的控制檯輸出。 – 2010-11-13 22:54:44

+0

if(waitError == WAIT_OBJECT_0)部分應跨越全部四行直到塊結束。如果打開&readThreadNextStatus從最裏面的循環中是錯誤的,那麼你不想打印你沒有的數據。 – Dialecticus 2010-11-13 23:23:49

+0

這是真的,謝謝,我改變了它。 – 2010-11-13 23:33:47