此代码中的哪个ReadFile参数不正确? (错误代码87)

时间:2016-04-20 20:56:10

标签: c++ port readfile

编辑:我没有排除除标题和main()函数括号之外的任何代码。此处列出的代码行之间没有任何内容。)

我使用ReadFile函数来读取这个COM3端口(它没有返回INVALID_HANDLE_VALUE或ERROR_FILE_NOT_FOUND):

LPCTSTR portName = "COM3" ;

HANDLE hSerial;
hSerial = CreateFile(portName,
                     GENERIC_READ | GENERIC_WRITE,
                     0,    // exclusive access
                     NULL, // default security attributes
                     OPEN_EXISTING,
                     FILE_FLAG_OVERLAPPED,
                     NULL);

有问题的ReadFile函数使用以下参数:

DWORD n = 512 ;
char szBuff[n] = {0};
DWORD dwBytesRead = 0;

if(!ReadFile(hSerial, szBuff, n, &dwBytesRead, NULL))
{
    cout << "ReadFile error. Error code: " << GetLastError() << endl ;
    cin.get() ;
    return 0 ;
}

我应该引入哪些更改才能使读取成功?

(我搜索了函数的文档和其他StackOverflow问题,测试了很多东西,但找不到答案。)

3 个答案:

答案 0 :(得分:5)

ReadFile文档中,您可以阅读:

  

lpOverlapped [in,out,optional]   如果使用FILE_FLAG_OVERLAPPED打开hFile参数,则需要指向OVERLAPPED结构的指针,否则它可以为NULL。

所以,既然您在CreateFile中指定了FILE_FLAG_OVERLAPPED,那么您应该在ReadFile中提供OVERLAPPED

CreateFile中,您可以阅读Communications Resources的参数:

  

...并且可以为重叠的I / O打开句柄

因此您可以在CreateFile中跳过FILE_FLAG_OVERLAPPED

答案 1 :(得分:1)

MarcinJędrzejewski对于重叠的IO标志与ReadFile功能之间的不匹配是正确的,但我会将其保留为有帮助。
您缺少大量初始化,这可能对您在操作COM端口时有所帮助。

此代码用于使用C ++从Windows上的COM端口打开,配置和读取。

供参考

READ_BUFFER_SIZE = 1024;
WRITE_BUFFER_SIZE = 1024;
COM_READ_BUFFER_SIZE = 1024;
COM_WRITE_BUFFER_SIZE = 1024;
READ_TIMEOUT = 50;
WRITE_TIMEOUT = 100;

port = "\\.\COM6"
portFormat = "9600,N,8,1" /* for information on this, google the MODE command for windows. */

HANDLE hComPort;
DCB dcbComConfig;

打开COM PORT

DWORD dwStoredFlags = EV_BREAK | EV_ERR | EV_RXCHAR;
COMMTIMEOUTS timeouts;

FillMemory(&dcbComConfig, sizeof(dcbComConfig), 0);
dcbComConfig.DCBlength = sizeof(dcbComConfig);

/* assign a COM format to the COM Port. */
if(!BuildCommDCB(portFormat, &dcbComConfig))
{
    printf("Failed to build comm format data %s\n", portFormat);
}

/* Open the COM port with overlapped IO. */
hComPort = CreateFile(port, GENERIC_READ | GENERIC_WRITE, 0, 0, 
                OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);

if (hComPort == INVALID_HANDLE_VALUE)
{
    printf("Error opening port %s\n", port);
}

/* Set the COM Ports internal Read and Write buffer sizes. */
if(!SetupComm(hComPort, COM_READ_BUFFER_SIZE, COM_WRITE_BUFFER_SIZE))
{
    printf("Could not set COM buffers\n");
}

/* assign the previously created COM Format to the COM Port. */
if(!SetCommState(hComPort, &dcbComConfig))
{
    printf("Error setting com to format data.\n");
}

/* Mask what events you want to look for in the COM Port. */
if (!SetCommMask(hComPort, dwStoredFlags))
{
    printf("Error setting communications mask\n");
}

/*-- Read Timeouts set like this so we can use the event based reading. --*/
timeouts.ReadIntervalTimeout = MAXDWORD; 
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.WriteTotalTimeoutMultiplier = 10;
timeouts.WriteTotalTimeoutConstant = 100;

if (!SetCommTimeouts(hComPort, &timeouts))
{
    printf("Error setting time-outs.\n");
}

阅读COM PORT

DWORD dwRead = 0;
DWORD dwComEvent = EV_RXCHAR;
DWORD lpErrors = 0;
char readBuffer[READ_BUFFER_SIZE];

/* Create the Overlapped IO Read Event. */
OVERLAPPED osRead = {0};
osRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

/* Used to monitor the COM Port State. */
COMSTAT ComStatus;

/* Loop at 20Hz to read the COM Port until a Kill event has been set. */
while(WaitForSingleObject(hKillEvent, 50) == WAIT_TIMEOUT)
{
    /* Wait for a COM Event to occur ( Read Event in this Case ). */
    if (WaitCommEvent(hComPort, &dwComEvent , NULL))
    {
        /* If the COM Port had an error Clear it. */
        ClearCommError(hComPort, &lpErrors, &ComStatus);
        /*-- Reset read operation's OVERLAPPED structure's hEvent --*/
        ResetEvent(osRead.hEvent);

        if (ReadFile(hComPort, readBuffer, ComStatus.cbInQue, &dwRead, &osRead))
        {
            /*-- bytes have been read; process it --*/
            USE_DATA(readBuffer, dwRead);
        }
        else
        {
            /*-- An error occurred in the ReadFile call --*/
            printf("ReadFile encountered an error.\n");
            break;
        }
    }
    else 
    {
        /*-- Error in WaitCommEvent --*/
        printf("WaitCommEvent encountered an error.\n");
        break;
    }
}

/* Close the Overlapped IO Read Event. */
CloseHandle(osRead.hEvent);

答案 2 :(得分:0)

最正确的答案是正确的。在这种情况下,以PARENT_SKU + COLON + ACTUAL_SKU打开,ReadFile期望将FILE_FLAG_OVERLAPPED结构作为最后一个参数。

想补充一点,如果您确实提供了OVERLAPPED结构,但忘记了OVERLAPPED,也会出现“参数不正确”错误。

documentation

  

在函数调用中使用该结构之前,应始终将该结构的任何未使用成员初始化为零。否则,该函数可能会失败并返回ERROR_INVALID_PARAMETER。

所以不要忘记:

ZeroMemory