我有一个非常奇怪的问题,我似乎无法弄清楚。不幸的是,我甚至不确定如何描述它而不描述我的整个应用程序。我想做的是:
1) read a byte from the serial port 2) store each char into tagBuffer as they are read 3) run a query using tagBuffer to see what type of tag it is (book or shelf tag) 4) depending on the type of tag, output a series of bytes corresponding to the type of tag
我的大部分代码都已实现,我可以将正确的标记代码发送回串口。但是我添加了两行作为调试语句,当我尝试删除它们时,它们会导致我的程序停止工作。
线条是最底部的两条线:
sprintf(buf,"%s!\n", tagBuffer);
WriteFile(hSerial,buf,strlen(buf), &dwBytesWritten,&ovWrite);
sprintf(buf,"%s!\n", tagBuffer);
WriteFile(hSerial,buf,strlen(buf), &dwBytesWritten,&ovWrite);
如果我尝试删除它们,“tagBuffer”将仅存储最后一个字符作为缓冲区。与下一行WriteFile()相同。
我认为sprintf和WriteFile是I / O函数,对变量没有影响。 我被困住了,我需要帮助解决这个问题。
//keep polling as long as stop character '-' is not read
while(szRxChar != '-')
{
// Check if a read is outstanding
if (HasOverlappedIoCompleted(&ovRead))
{
// Issue a serial port read
if (!ReadFile(hSerial,&szRxChar,1,
&dwBytesRead,&ovRead))
{
DWORD dwErr = GetLastError();
if (dwErr!=ERROR_IO_PENDING)
return dwErr;
}
}
// resets tagBuffer in case tagBuffer is out of sync
time_t t_time = time(0);
char buf[50];
if (HasOverlappedIoCompleted(&ovWrite))
{
i=0;
}
// Wait 5 seconds for serial input
if (!(HasOverlappedIoCompleted(&ovRead)))
{
WaitForSingleObject(hReadEvent,RESET_TIME);
}
// Check if serial input has arrived
if (GetOverlappedResult(hSerial,&ovRead,
&dwBytesRead,FALSE))
{
// Wait for the write
GetOverlappedResult(hSerial,&ovWrite,
&dwBytesWritten,TRUE);
if( strlen(tagBuffer) >= PACKET_LENGTH )
{
i = 0;
}
//load tagBuffer with byte stream
tagBuffer[i] = szRxChar;
i++;
tagBuffer[i] = 0; //char arrays are \0 terminated
//run query with tagBuffer
sprintf(query,"select type from rfid where rfidnum=\"");
strcat(query, tagBuffer);
strcat(query, "\"");
mysql_real_query(&mysql,query,(unsigned int)strlen(query));
//process result and send back to handheld
res = mysql_use_result(&mysql);
while(row = mysql_fetch_row(res))
{
printf("result of query is %s\n",row[0]);
string str = "";
str = string(row[0]);
if( str == "book" )
{
WriteFile(hSerial,BOOK_INDICATOR,strlen(BOOK_INDICATOR),
&dwBytesWritten,&ovWrite);
}
else if ( str == "shelf" )
{
WriteFile(hSerial,SHELF_INDICATOR,strlen(SHELF_INDICATOR),
&dwBytesWritten,&ovWrite);
}
else //this else doesn't work
{
WriteFile(hSerial,NOK,strlen(NOK),
&dwBytesWritten,&ovWrite);
}
}
mysql_free_result(res);
// Display a response to input
//printf("query is %s!\n", query);
//printf("strlen(tagBuffer) is %d!\n", strlen(tagBuffer));
//without these, tagBuffer only holds the last character
sprintf(buf,"%s!\n", tagBuffer);
WriteFile(hSerial,buf,strlen(buf), &dwBytesWritten,&ovWrite);
}
}
使用这两行,我的输出如下所示: s sh she shel shelf shelf0 shelf00 BOOKCODE shelf0001
没有它们,我发现tagBuffer和buf只能在任何时候存储最新的字符。
任何帮助都将非常感谢。感谢。
答案 0 :(得分:1)
你在哪里分配tagbuffer,它有多大? 你可能会覆盖'buf',因为你正在写过tagbuffer的结尾。
答案 1 :(得分:1)
这两行似乎不太可能对正确的程序产生影响 - 也许你没有在buf
中为tagBuffer
中的字符串的整个长度分配足够的空间?这可能导致缓冲区溢出,掩盖了真正的问题?
答案 2 :(得分:1)
我要说的第一件事是一条一般建议:错误并不总是你认为的错误。如果你有一些事情似乎没有意义,那通常意味着你在其他地方做出的假设是错误的。
这里,sprintf()和WriteFile()似乎不太可能改变“buf”数组变量的状态。但是,这两行测试代码写入“hSerial”,而主循环也读取“hSerial”。这听起来像是一个改变你的程序行为的人。
建议:更改调试输出行以将输出存储在其他位置:对话框,日志文件或类似文件。调试输出通常不应该转到核心逻辑中使用的文件,因为这很可能会改变核心逻辑的行为。
答案 3 :(得分:0)
在我看来,这里真正的问题是你试图从一个线程读取和编写串口,这使得代码变得比它需要的更复杂。我建议您阅读以下文章并重新考虑您的设计:
在多线程实现中,只要读者线程从串行端口读取消息,您就会将其发布到应用程序的主线程中。然后,主线程将解析消息并查询数据库,然后将相应的响应排入编写器线程。
这可能听起来比你当前的设计更复杂,但事实并非像Newcomer所解释的那样。
我希望这有帮助!