这ReadFile的参数在这个代码是不正确的? (错误代码87)

问题描述 投票:0回答:3

(编辑:我不排除任何代码,除了头和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问题搜索,测试很多东西,但无法找到答案。)

c++ port readfile
3个回答
5
投票

ReadFile文档,你可以阅读:

lpOverlapped的[IN,OUT,可选]一个指向如果HFILE参数用FILE_FLAG_OVERLAPPED打开是必需的OVERLAPPED结构,否则它可以为NULL。

所以,因为你在指定的CreateFile你FILE_FLAG_OVERLAPPED应该ReadFile的提供OVERLAPPED

CreateFile你可以对Communications Resources参数如下:

...和手柄可以重叠I / O打开。

所以你可以跳过的CreateFile FILE_FLAG_OVERLAPPED


1
投票

马尔钦·杰德泽朱厄斯基的回答是关于重叠IO标志和ReadFile功能之间的不匹配是正确的,但我会离开这件事只是对大家有所帮助。 这是因为丢失了大量的初始化操作的COM端口时可能对您有所帮助。

该代码用于打开,配置和从COM端口读取关于使用C ++的窗户。

以供参考

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端口

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端口

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

0
投票

顶端回答是正确的。在这种情况下,与打开FILE_FLAG_OVERLAPPED,ReadFile的期望一个OVERLAPPED结构作为最后一个参数。

想补充一点,你还可以得到“参数不正确”的错误,如果你提供一个OVERLAPPED结构,但忘了ZeroMemory它。

documentation

在函数调用时所用的结构之前,这个结构的任何未使用的成员应该总是初始化为零。否则,该功能可能会失败,并返回ERROR_INVALID_PARAMETER。

所以,不要忘记:

OVERLAPPED ovl;
ZeroMemory(&ovl, sizeof(ovl));
...
ReadFile(hSerial, szBuff, n, &dwBytesRead, &ovl);
© www.soinside.com 2019 - 2024. All rights reserved.