2

MSDN は、ReadFile()機能の説明で次のように述べています。

hFile が で開かれる場合FILE_FLAG_OVERLAPPED、lpOverlapped パラメータは有効で一意の構造体を指す必要がありますOVERLAPPED。そうしないと、関数が読み取り操作が完了したと誤って報告する可能性があります。

上記の推奨事項に違反しているアプリケーションがいくつかあり、問題の深刻度を知りたいです。つまり、プログラムは で作成された名前付きパイプをFILE_FLAG_OVERLAPPED使用しますが、次の呼び出しを使用してそこから読み取ります。

ReadFile(handle, &buf, n, &n_read, NULL);

つまりNULL、パラメーターとして渡されlpOverlappedます。ドキュメントによると、その呼び出しは状況によっては正しく機能しないはずです。問題を再現するために多くの時間を費やしましたが、再現できませんでした! 私は常にすべてのデータを適切な場所に適切なタイミングで取得しました。ただし、名前付きパイプのみをテストしていました。

ReadFile() が誤って返され、データがまだバッファにない場合でも正常に完了したことを報告することを期待できるのはいつですか? 問題を再現するにはどうすればよいですか? ファイル、パイプ、ソケット、コンソール、またはその他のデバイスで発生しますか? 特定のバージョンの OS を使用する必要がありますか? または特定のバージョンの読み取り (ハンドルを I/O 完了ポートに登録するなど)? または、プロセス/スレッドの読み取りと書き込みの特定の同期?

または、いつ失敗しますか?わたしにはできる :/

助けてください!

よろしく、 マーティン

4

4 に答える 4

0

文書化されたベストプラクティスに違反して意図的にAPIを呼び出している状況にあるようです。そのような状況では、すべての賭けはオフになります。うまくいくかもしれませんし、うまくいかないかもしれません。このOSで機能する可能性があるが、OSの次のイテレーション、または同じOSの次のサービスパックでは機能しない場合。Win64に移植するとどうなりますか?それでも機能しますか?

GetLastError()を呼び出す(またはデバッガーで@ ERR、hrを調べる)と、エラーコードに加えて役立つ値が得られますか?

有効なOVERLAPPED構造で呼び出し、機能させて、すべての疑い(およびランダムな失敗の可能性)を取り除くことをお勧めします。有効なOVERLAPPED構造を使用して問題を簡単に修正できるのに、ソフトウェアにバグのあるコード(およびバグの再現が非常に難しい)があるのはなぜですか?

于 2010-03-18T19:47:42.637 に答える
0

彼らが言うとき

Blockquote hFile が FILE_FLAG_OVERLAPPED で開かれる場合、lpOverlapped パラメータは有効で一意の OVERLAPPED 構造体を指す必要があります。そうしないと、関数が読み取り操作が完了したと誤って報告する可能性があります。

コードには動作を妨げるものは何もありませんが、誤った結果を生成する可能性のあるコード内のパスもあります。特定のハードウェアで問題を再現できないからといって、問題がないわけではありません。

この問題を本当に再現したい場合は、コードをそのままにして、自分の人生を続けてください。この問題をすっかり忘れてしまった頃に、ReadFile の呼び出しとは明らかに関係のない奇妙な動作が表面化します。何日もかけて髪を引き抜くと、問題がランダムに現れたり消えたりするように見えます。最終的にはそれを見つけて、指示に従わないことで自分を蹴るでしょう. そこに行った、それをした、面白くない!

問題を再現するもう 1 つの方法は、顧客のために重要なデモをスケジュールすることです。そしたら失敗間違いなし!

OVERLAPPED 構造と関連するすべての戻り値チェック、待機、イベントなどでコードを飛び散らせたくない場合は、読み取り元のハンドルとタイムアウトを受け取るラッパー関数を作成できます。ReadFile への呼び出しをこの便利なラッパーに置き換えるだけです。

于 2010-11-02T01:27:50.733 に答える
0

意図したとおりに API を呼び出すようにコードを修正するのではなく、なぜ質問をするのでしょうか?

これは非同期 I/O ですが、非常に迅速に完了するため、常に機能しているように見えると思います。成功をテストする方法によっては、操作が完了したと関数が誤って報告している可能性がありますが、結果をテストする前に実際には完了しています。

実際のテストは、読み取るデータが存在する前にパイプで読み取りを行うことです。

しかし、実際には、コードを修正する必要があります。アーキテクチャが非同期 I/O を処理できない場合FILE_FLAG_OVERLAPPEDは、名前付きパイプの作成から を削除します。

于 2010-03-18T20:12:28.943 に答える