简体   繁体   English

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

[英]Which ReadFile parameter in this code is incorrect? (Error code 87)

( Edit: I didn't exclude any code except the headers and the main() function's brackets. Nothing is written between lines of code listed here.) 编辑:除了标题和main()函数的括号外,我没有排除任何代码。此处列出的代码行之间没有编写任何内容。)

.

I used the ReadFile function to read this COM3 port (which returned no INVALID_HANDLE_VALUE or ERROR_FILE_NOT_FOUND): 我使用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);

And the ReadFile function in question uses following parameters: 有问题的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 ;
}

What changes should I introduce to cause the read to succeed? 我应该进行哪些更改才能使读取成功?

(I searched through the function's documentation and other StackOverflow questions, tested lots of things, but couldn't find an answer.) (我搜索了该函数的文档和其他StackOverflow问题,测试了很多东西,但找不到答案。)

In ReadFile documentation you can read: ReadFile文档中,您可以阅读:

lpOverlapped [in, out, optional] A pointer to an OVERLAPPED structure is required if the hFile parameter was opened with FILE_FLAG_OVERLAPPED, otherwise it can be NULL. lpOverlapped [输入,输出,可选]如果使用FILE_FLAG_OVERLAPPED打开了hFile参数,则需要指向OVERLAPPED结构的指针,否则它可以为NULL。

so since you specified FILE_FLAG_OVERLAPPED in CreateFile you should provide OVERLAPPED in ReadFile. 因此,由于您在CreateFile中指定了FILE_FLAG_OVERLAPPED ,因此您应该在ReadFile中提供OVERLAPPED

In CreateFile you can read on parameters for Communications Resources : CreateFile中,您可以阅读Communications Resources参数:

... and the handle can be opened for overlapped I/O. ...并且可以打开手柄进行重叠的I / O。

so you can skip FILE_FLAG_OVERLAPPED in CreateFile 因此您可以跳过CreateFile中的FILE_FLAG_OVERLAPPED

Marcin Jędrzejewski's answer is correct about the mismatch between the overlapped IO Flag and the ReadFile function, but I will leave this up just to be helpful. 关于重叠的IO标志和ReadFile函数之间的不匹配,MarcinJędrzejewski的答案是正确的,但我将其保留以作参考。
You are missing a lot of initialisation which may be helpful to you when operating a COM port. 您缺少许多初始化信息,这些信息可能对操作COM端口有帮助。

This code is used to open, configure, and read from a COM port on windows using C++. 此代码用于使用C ++在Windows上的COM端口打开,配置和读取。

FOR REFERENCE 以供参考

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;

OPENING COM PORT 打开COM端口

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");
}

READING COM PORT 阅读COM端口

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);

The top answer is correct. 最高答案是正确的。 In this case, opening with FILE_FLAG_OVERLAPPED , ReadFile expects an OVERLAPPED structure as last argument. 在这种情况下,以FILE_FLAG_OVERLAPPED打开,ReadFile期望将OVERLAPPED结构作为最后一个参数。

Would like to add that you can also get 'parameter is incorrect' error if you do supply an OVERLAPPED struct, but forget to ZeroMemory it. 还要补充一点,如果您确实提供了OVERLAPPED结构,但也忘记将它存储到ZeroMemory ,那么也会出现“参数不正确”错误。

From the documentation : 文档中

Any unused members of this structure should always be initialized to zero before the structure is used in a function call. 在函数调用中使用该结构之前,应始终将该结构的任何未使用成员初始化为零。 Otherwise, the function may fail and return ERROR_INVALID_PARAMETER. 否则,该函数可能会失败并返回ERROR_INVALID_PARAMETER。

So don't forget to: 因此,请不要忘记:

OVERLAPPED ovl;
ZeroMemory(&ovl, sizeof(ovl));
...
ReadFile(hSerial, szBuff, n, &dwBytesRead, &ovl);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM