(编辑:我没有排除除标题和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问题,测试了很多东西,但找不到答案。)
答案 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;
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);
答案 2 :(得分:0)
最正确的答案是正确的。在这种情况下,以PARENT_SKU + COLON + ACTUAL_SKU
打开,ReadFile期望将FILE_FLAG_OVERLAPPED
结构作为最后一个参数。
想补充一点,如果您确实提供了OVERLAPPED
结构,但忘记了OVERLAPPED
,也会出现“参数不正确”错误。
在函数调用中使用该结构之前,应始终将该结构的任何未使用成员初始化为零。否则,该函数可能会失败并返回ERROR_INVALID_PARAMETER。
所以不要忘记:
ZeroMemory