1

私は非常に奇妙な問題を抱えていますが、それは理解できないようです。残念ながら、アプリケーション全体を説明せずに説明する方法すらわかりません。私がやろうとしていることは:

1)シリアルポートからバイトを読み取る
2)読み取​​られた各文字をtagBufferに格納します
3)tagBufferを使用してクエリを実行し、タグのタイプ(本または棚のタグ)を確認します。
4)タグの種類に応じて、タグの種類に対応する一連のバイトを出力します

私のコードのほとんどは実装されており、正しいタグコードをシリアルポートから送り返すことができます。しかし、デバッグステートメントとして追加した2行があり、それらを削除しようとすると、プログラムが機能しなくなります。

線は一番下の2本の線です。

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

    }
}

これらの2行を使用すると、私の出力は次のようになります。

それらがないと、tagBufferとbufは常に最新の文字のみを格納することがわかりました。

どんな助けでも大歓迎です。ありがとう。

4

4 に答える 4

1

タグバッファはどこに割り当てていますか、どのくらいの大きさですか?
タグバッファの終わりを超えて書き込んでいるため、「buf」を上書きしている可能性があります。

于 2008-11-09T07:57:29.027 に答える
1

これらの2行が正しいプログラムにその影響を与える可能性は低いようです-おそらくbuf、文字列の全長に十分なスペースを割り当てていませんtagBufferか?これにより、実際の問題を偽装しているバッファオーバーランが発生する可能性がありますか?

于 2008-11-09T07:58:58.930 に答える
1

私が最初に言うことは、一般的なアドバイスの一部です。バグは、必ずしもあなたが思っている場所にあるとは限りません。意味をなさないようなことが起こっている場合、それは多くの場合、どこか別の場所での仮定が間違っていることを意味します。

ここでは、sprintf()とWriteFile()が「buf」配列変数の状態を変更する可能性は非常に低いようです。ただし、これらの2行のテストコードは「hSerial」に書き込みますが、メインループも「hSerial」から読み取ります。それはあなたのプログラムの振る舞いを変えるためのレシピのように聞こえます。

提案:デバッグ出力の行を変更して、出力を別の場所(ダイアログボックス、ログファイルなど)に保存します。デバッグ出力は、コアロジックの動作を変更する可能性が非常に高いため、通常、コアロジックで使用されるファイルに送信しないでください。

于 2008-11-09T08:06:43.827 に答える
0

私の意見では、ここでの本当の問題は、単一のスレッドからシリアル ポートを読み書きしようとしているということです。これにより、コードが必要以上に複雑になっています。次の記事を読んで、デザインを再考することをお勧めします。

マルチスレッド実装では、リーダー スレッドがシリアル ポートからメッセージを読み取るたびに、それをアプリケーションのメイン スレッドにポストします。次に、メイン スレッドはメッセージを解析してデータベースにクエリを実行し、ライター スレッドへの適切な応答をキューに入れます。

これは現在の設計よりも複雑に聞こえるかもしれませんが、実際にはそうではありません、と Newcomer は説明します。

これが役立つことを願っています!

于 2008-11-09T12:16:28.473 に答える