3

わかりました、SO ハイブ マインド用の 1 つ...

今日まで、多くのシステムで問題なく動作し、多くのサイトに展開されているコードがあります。これには、シリアル ポートからデータを読み書きするスレッドが含まれます。

新しいデバイスをチェックアウトしようとすると、ReadFile の後に GetOverlappedResult を呼び出す 995 の ERROR_OPERATION_ABORTED エラーでコードがあふれていました。読み取りが機能することもあれば、このエラーが発生することもあります。エラーを無視して再試行するだけで、驚くべきことに、データを削除せずに機能します。ClearCommError は必要ありません。

これがスニペットです。

if (!ReadFile(handle,&c,1,&read, &olap))
    {
        if (GetLastError() != ERROR_IO_PENDING)
        {
            logger().log_api(LOG_ERROR,"ser_rx_char:ReadFile");
            throw Exception("ser_rx_char:ReadFile");
        }
    }

    WaitForSingleObjectEx(r_event, INFINITE, true);  // alertable, so, thread can be closed correctly.

    if (GetOverlappedResult(handle,&olap,&read, TRUE) != 0)
    {
        if (read != 1)
            throw Exception("ser_rx_char: no data");

        logger().log(LOG_VERBOSE,"read char %d ( read = %d) ",c, read);
    }
    else
    {
        DWORD err = GetLastError();
        if (err != 995)   //Filters our ERROR_OPERATION_ABORTED
        {
            logger().log_api(LOG_ERROR,"ser_rx_char: GetOverlappedResult");
            throw Exception("ser_rx_char:GetOverlappedResult");
        }
    }

私の最初の推測は、以前に使用したことのない COM ポート ドライバーのせいだと思います (参考までに、Blackmagic Decklink の RS422 ポートです)。

ああ、Vista SP1 Business 32 ビット、念のため。

これを「他の誰かの問題」に分類する前に、これを引き起こす原因について何か考えがある人はいますか?

4

2 に答える 2

4

ReadFile の前に OVERLAPPED 構造をどのように設定していますか? - 私は常に (明らかに hEvent を除いて) それらをゼロにします。これはおそらく迷信の一部ですが、過去に問題が発生したと感じています。

残念ながら、ドライバーを非難することは (それが MS ではなく、リファレンスからのわずかな微調整ではない場合)、完全に非現実的ではありません。COM ドライバーを作成することは信じられないほど複雑なことであり、それをテストするのが難しいのは、これまでに作成されたすべてのアプリケーションがシリアル ポートとその IOCTL をわずかに異なる方法で使用することです。

もう 1 つの一般的な問題は、ポート全体を設定しないことです。たとえば、SetCommTimeouts または SetupComm を呼び出さないことです。あなたがこの種の間違いを犯しているかどうかはわかりませんが、実際には SetCommTimeouts を呼び出さなかったのでタイムアウトを使用していないのでタイムアウトを使用していないと言い、タイムアウトを使用していないと言う人に会ったことがあります。彼らが何に設定されているかという概念...

この種のことは、サードパーティの COM ドライバーにとって致命的となる可能性があります。なぜなら、人々は MS ドライバーを使って古いがらくたを回避することが多く、別のデバイスでは常に同じように動作するとは限らないからです。

于 2008-11-20T23:27:19.277 に答える