1

我有一个非常奇怪的问题,我似乎无法弄清楚。不幸的是,如果不描述我的整个应用程序,我什至不确定如何描述它。我想做的是:

1)从串口读取一个字节
2) 在读取每个字符时将它们存储到 tagBuffer 中
3) 使用 tagBuffer 运行查询以查看它是什么类型的标签(书或书架标签)
4)根据标签类型,输出标签类型对应的一系列字节

我的大部分代码都已实现,我可以将正确的标签代码从串行端口发送回。但是我添加了两行作为调试语句,当我试图删除它们时,它们会导致我的程序停止工作。

这些行是最底部的两行:

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

    }
}

有了这两行,我的输出如下所示:

没有它们,我发现 tagBuffer 和 buf 在任何时候都只存储最近的字符。

任何帮助都将不胜感激。谢谢。

4

4 回答 4

1

你在哪里分配标签缓冲区,它有多大?
您可能正在覆盖“buf”,因为您正在写入标签缓冲区的末尾。

于 2008-11-09T07:57:29.027 回答
1

这两行似乎不太可能对正确的程序产生这种影响 - 也许您没有为 inbuf字符串的整个长度分配足够的空间tagBuffer?这可能会导致掩盖真正问题的缓冲区溢出?

于 2008-11-09T07:58:58.930 回答
1

我要说的第一件事是一条一般性建议:错误并不总是在您认为的位置。如果你正在发生的事情似乎没有意义,这通常意味着你在其他地方的假设是错误的。

在这里,sprintf() 和 WriteFile() 似乎不太可能改变“buf”数组变量的状态。但是,这两行测试代码确实写入“hSerial”,而您的主循环也从“hSerial”读取。这听起来像是改变程序行为的方法。

建议:更改您的调试输出行以将输出存储到其他位置:对话框、日志文件或类似文件。调试输出通常不应该转到核心逻辑中使用的文件,因为这很可能会改变核心逻辑的行为方式。

于 2008-11-09T08:06:43.827 回答
0

在我看来,这里真正的问题是您试图从单个线程读取和写入串行端口,这使得代码比它需要的更复杂。我建议您阅读以下文章并重新考虑您的设计:

在多线程实现中,每当阅读器线程从串行端口读取消息时,您就会将其发布到应用程序的主线程。然后主线程将解析消息并查询数据库,然后将适当的响应排队到写入线程。

这听起来可能比您当前的设计更复杂,但实际上并非如此,正如 Newcomer 解释的那样。

我希望这有帮助!

于 2008-11-09T12:16:28.473 回答