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

C++ 此代码中的哪个ReadFile参数不正确?(错误代码87),c++,port,readfile,C++,Port,Readfile,(Edit:除了头和main()函数的括号外,我没有排除任何代码。这里列出的代码行之间没有写入任何内容。) 我使用ReadFile函数读取这个COM3端口(没有返回无效的\u HANDLE\u值或错误\u FILE\u NOT\u FOUND): 所讨论的ReadFile函数使用以下参数: DWORD n = 512 ; char szBuff[n] = {0}; DWORD dwBytesRead = 0; if(!ReadFile(hSerial, szBuff, n, &dwB

Edit:除了头和main()函数的括号外,我没有排除任何代码。这里列出的代码行之间没有写入任何内容。)

我使用ReadFile函数读取这个COM3端口(没有返回无效的\u HANDLE\u值或错误\u FILE\u NOT\u FOUND):

所讨论的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 ;
}
dwordn=512;
char szBuff[n]={0};
DWORD-dwBytesRead=0;
if(!ReadFile(hSerial、szBuff、n和dwBytesRead,NULL))
{

coutMarcin Jędrzejewski关于重叠IO标志和
ReadFile
函数之间不匹配的回答是正确的,但我将把这个留给大家,只是为了有所帮助。
在操作COM端口时,您缺少许多可能对您有帮助的初始化

此代码用于使用C++、./P>在Windows上打开、配置和读取COM端口。 供参考 打开COM端口 读取COM端口


Marcin Jędrzejewski关于重叠IO标志和
ReadFile
函数之间不匹配的回答是正确的,但我将保留这一点,只是为了有所帮助。
在操作COM端口时,您缺少许多可能对您有帮助的初始化

此代码用于使用C++、./P>在Windows上打开、配置和读取COM端口。 供参考 打开COM端口 读取COM端口 在文档中,您可以阅读:

lpOverlapped[输入、输出、可选] 如果在打开hFile参数时文件\u标志\u重叠,则需要指向重叠结构的指针,否则它可以为NULL

因此,既然您在CreateFile中指定了
FILE\u FLAG\u OVERLAPPED
,那么您应该在ReadFile中提供
OVERLAPPED

在中,您可以阅读
通信资源的参数:

…并且可以为重叠I/O打开手柄

因此,您可以跳过CreateFile中的
文件\u标志\u重叠
,在您可以阅读的文档中:

lpOverlapped[输入、输出、可选] 如果在打开hFile参数时文件\u标志\u重叠,则需要指向重叠结构的指针,否则它可以为NULL

因此,既然您在CreateFile中指定了
FILE\u FLAG\u OVERLAPPED
,那么您应该在ReadFile中提供
OVERLAPPED

在中,您可以阅读
通信资源的参数:

…并且可以为重叠I/O打开手柄


因此,您可以跳过CreateFile中的
FILE\u FLAG\u OVERLAPPED
顶部答案是正确的。在这种情况下,使用
FILE\u FLAG\u OVERLAPPED
打开时,ReadFile需要一个
OVERLAPPED
结构作为最后一个参数

要补充的是,如果您确实提供了一个
重叠的
结构,但忘记了
零内存
它,您也可以得到“参数不正确”错误

从:

在函数调用中使用此结构之前,此结构的任何未使用成员都应始终初始化为零。否则,函数可能会失败并返回错误\u无效\u参数

所以别忘了:

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

上面的答案是正确的。在这种情况下,以
FILE\u FLAG\u OVERLAPPED
打开时,ReadFile需要一个
OVERLAPPED
结构作为最后一个参数

要补充的是,如果您确实提供了一个
重叠的
结构,但忘记了
零内存
它,您也可以得到“参数不正确”错误

从:

在函数调用中使用此结构之前,此结构的任何未使用成员都应始终初始化为零。否则,函数可能会失败并返回错误\u无效\u参数

所以别忘了:

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

您将一个值赋给
hSerial
,然后1)您从未检查过NULL,2)您的代码在
ReadFile
函数中消失并再次出现,丢失了
hSerial
@Paul I checked
hSerial
在创建后立即发生的任何事件-非NULL。并且
ReadFile
立即发生创建
hSerial
。仍然是87。
LPCTSTR portName=“COM3”
您可能需要更改此设置,因为如果正在进行Unicode构建,则
LPCTSTR
是指向宽字符串的指针。
LPCTSTR portName=_T(“COM3”)
我假设它是用mingw而不是Unicode编译的,例如:
DWORD n=512;char szBuff[n]={0};
是一个可变长度数组,CreateFileW不接受
char
数组。@MarcinJędrzejewski是的,但是“正式地”,将LPCTSTR初始化为非宽字符串文本实际上不是100%正确。如果应用程序要使用
LPCTSTR
,那么如果使用
,则应该使用Microsoft ism
macro或
TEXT
macro。您为
hSerial
指定一个值,然后1)您从未检查过NULL,2)您的代码消失并再次出现在
ReadFile
函数中,丢失了
hSerial
@Paul I checked
hSerial
在创建后立即发生的任何跟踪信息-不为NULLode>ReadFile
在创建
hSerial
后立即发生。仍然87。
LPCTSTR portName=“COM3”
您可能需要更改这一点,因为如果正在进行Unicode构建,
LPCTSTR
是指向宽字符串的指针。
LPCTSTR portName=\u T(“COM3”)
我想它是用mingw编译的,没有UNICODE,例如:
DWORD n=512;char szBuff[n]={0};
是一个可变长度数组,CreateFileW不会接受
char
数组。@MarcinJędrzejewski是的,但“正式”,将LPCTSTR初始化为非宽字符串文字并不是100%正确。如果应用程序要使用
LPCTSTR
,则如果使用
\T()
宏或
文本
宏,则应使用Microsoft ism。
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");
}
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);
OVERLAPPED ovl;
ZeroMemory(&ovl, sizeof(ovl));
...
ReadFile(hSerial, szBuff, n, &dwBytesRead, &ovl);