(编辑:我不排除任何代码,除了头和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问题搜索,测试很多东西,但无法找到答案。)
在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
马尔钦·杰德泽朱厄斯基的回答是关于重叠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;
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);
顶端回答是正确的。在这种情况下,与打开FILE_FLAG_OVERLAPPED
,ReadFile的期望一个OVERLAPPED
结构作为最后一个参数。
想补充一点,你还可以得到“参数不正确”的错误,如果你提供一个OVERLAPPED
结构,但忘了ZeroMemory
它。
在函数调用时所用的结构之前,这个结构的任何未使用的成员应该总是初始化为零。否则,该功能可能会失败,并返回ERROR_INVALID_PARAMETER。
所以,不要忘记:
OVERLAPPED ovl;
ZeroMemory(&ovl, sizeof(ovl));
...
ReadFile(hSerial, szBuff, n, &dwBytesRead, &ovl);