2013-04-13 35 views
1

我試圖用C++編寫一個串行端口與WIN32 API,WriteFile不會返回ERROR_IO_PENDING,但沒有任何反應,但是在我寫使用其他程序的端口(C#)的C++程序的工作,直到我重新啓動windows 7,這裏是寫代碼:使用win32 API寫入串行端口 - 端口將不會打開,直到我打開它其他地方

static DCB dcb = {0}; 
static HANDLE hComm; 
static int _tmain(int argc, _TCHAR* argv[]) 
{ 
    hComm = CreateFile(
    L"\\\\.\\COM3", 
    GENERIC_WRITE | GENERIC_READ, 
    0, 
    NULL, 
    OPEN_EXISTING, 
    NULL, 
    NULL 
    ); 

if (hComm == INVALID_HANDLE_VALUE) // error opening port; abort 
    printf_s("INVALID_HANDLE_VALUE\n"); 

if (GetCommState(hComm, &dcb))// DCB is ready for use. 
{ 
    dcb.BaudRate = CBR_19200; //19200 Baud 
    dcb.ByteSize = 8; //8 data bits 
    dcb.Parity = NOPARITY; //no parity 
    dcb.StopBits = ONESTOPBIT; //1 stop 
    printf_s("set UP DCB\n"); 
} 
else // Error getting current DCB settings 
    printf_s("ERROR getting \n"+GetLastError()); 

osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 

    WriteABuffer("!serialCMDtoSend\r",sizeof("!serialCMDtoSend\r"); 
} 
static BOOL WriteABuffer(char * lpBuf, DWORD dwToWrite) 
{ 
     // Issue write. 
     if (!WriteFile(hComm, lpBuf, dwToWrite, &dwWritten, &osWrite)) 
     { 
      if (GetLastError() != ERROR_IO_PENDING) { // WriteFile failed, but it isn't delayed. Report error and abort. 
       fRes = FALSE; 
      } 
      else { 
       // Write is pending. 
       if (!GetOverlappedResult(hComm, &osWrite, &dwWritten, TRUE)) 
        fRes = FALSE; 
       else 
        fRes = TRUE;// Write operation completed successfully. 
      } 
     } 
     else 
      fRes = TRUE;  // WriteFile completed immediately. 
    return fRes; 
} 

有誰能夠看到我的錯誤?

回答

0

有時以乾淨的DCB開始比使用GetCommState好。例如,您不關閉流量控制,因此行爲取決於最後一個程序如何離開它。

你一定要正確設置流量控制字段:

fOutxCtsFlow 
fOutxDsrFlow 
fDtrControl 
fDsrSensitivity 
fOutX 
fInX 
fRtsControl 

一般情況下,我建議不要使用GetCommState,如果你不想讓你的程序依賴於先前的設置。相反,開始一切爲零。

DCB dcb = { sizeof dcb }; 
dcb.fBinary = TRUE; 
dcb.BaudRate = 19200; //19200 Baud 
dcb.ByteSize = 8; //8 data bits 
dcb.Parity = NOPARITY; //no parity 
dcb.StopBits = ONESTOPBIT; //1 stop 

除了您先前設置的依賴,GetCommState失敗,因爲你沒有設置DCBlength(文檔清晰地說,這必須由您設置,來電GetCommState能在沒有首先檢查你提供的尺寸的情況下填充緩衝區。)。

+0

,我試圖faloow的示例是從MSDN: http://msdn.microsoft.com/en-us/library/ff802693.aspx 那裏它們復位DCB這樣的: DCB DCB = {0} ; – user1120007

+0

@ user1120007:我報告過文檔錯誤。調用'GetCommState'之前需要設置'DCBlength'成員。這對於接受結構的Win32 API非常常見,因爲結構大小可以在Windows版本之間改變,所以您需要告訴Windows Windows程序使用的結構的大小(版本)。 (否則將沒有理由在結構中有所有尺寸) –

1

這是偶然的。您忘記在CreateFile調用中指定FILE_FLAG_OVERLAPPED,因此您永遠不會獲得重疊的I/O。你可能不知道這個,因爲你的錯誤處理被破壞,當GetLastError沒有返回ERROR_IO_PENDING時,你不知道錯誤代碼是什麼樣的。由於數據適合驅動程序的發送緩衝區,因此WriteFile不必阻塞時它會無意中工作。按照Ben的解釋,模擬握手設置。

使用重疊的I/O並立即調用GetOverlappedResult(TRUE)毫無意義。您也可以使用非重疊的I/O,更容易。只有在你有其他有用的事情時才使用它,並且可以調用WaitForMultipleObjects()來檢查寫入是否完成。在寫作的情況下通常很難處理,編寫異步代碼並不容易。

+0

但我試圖做一個非重疊的溝通 – user1120007

+0

然後不要。傳遞NULL而不是&osWrite。 –