2017-08-04 13 views
0

Cコードを使用してジョイスティックからデータを読み取ろうとしています。私はfound online the way to do itです。コードを停止せずにread()C関数を使用します。

この解決策はうまくいくようですが、問題があります。コードが読み取り()関数をreachersときジョイスティックデバイスに変更があるまで、それが停止して待機:

int read_event(int fd, struct js_event *event) 
{ 
    ssize_t bytes; 

    bytes = read(fd, event, sizeof(*event)); 
    if (bytes == sizeof(*event)) 
     return 0; 
    return -1; 
} 

私は継続的にコードの実行を作るための方法を見つけようとしていないがある場合によ制御装置の変更、前の状態を返すだけです。これまで私は成功しなかった。たぶん誰かが助けることができます。

+2

あなたはファイルディスクリプタを 'open'しましたか? –

+2

2つのオプション - [select(2)](http://man7.org/linux/man-pages/man2/select.2.html)またはスレッド。 @EugeneSh。 –

+0

私はそれを開いた: device = "/ dev/input/js0"; js = open(デバイス、O_RDONLY);元のリンクのように –

答えて

2

あなたはopen()を経由して、ジョイスティックデバイスを開き、read()を経由して、それから読んでいることを考えると、私はあなたがPOSIXインターフェイスを実装して、マシンをコードしていることを推測します。ほとんどのファイルでは、POSIX read()は、少なくとも1バイトを転送できるようになるまで機能しません。これは実際に観察される動作です。

ファイルを非ブロックモードで開くか、ファイルを開いた後で読み込む前に非ブロックモードにすることを避ける方法の1つです。あなたが開いているオプションにO_NONBLOCKフラグを追加することで、元の操作を行うことができますジョイスティックイベントを読み取るための既存のコードをきれいにし、有利に相互作用する必要があり

js = open(device, O_RDONLY | O_NONBLOCK); 

。イベントを読み取ることができない場合は、read()呼び出しが戻り値-1で、errnoEAGAINに設定された状態で、すぐに戻ります。そうでなければ、転送されたバイト数を返します。

通常、read()は、要求されたバイト数を完全に転送することは保証されていません - 返り値から正しく判別でき、悲しみに来ることができます。しかし、私はあなたがジョイスティック・デバイスから短いリードを見ることはないと思います。あなたは完全な出来事か何かを得なければなりません。

0

私は実際のAPI(システムコール)機能についてはわかりませんが、私の考えはうまくいくはずです。

GetNumberOfInputEvents(WinAPI関数)のようなものを使用して、読み込みがスタックされているかどうかを判断します(読み込みなし)。そして、それが固まったと判断すれば、それをスキップしてください。

詳細については、Checking the stdin buffer if it's emptyを参照してください。

擬似コード:

read_event(Event* event){ 
    if (is_event_buffer_empty()) 
     // Do nothing because `read` is stuck 
    else 
     SystemAPI_ReadEvent(event); 
} 
+1

これは非常に間違っています。 'is_event_buffer_empy()'の後でデータが利用できなくなる可能性があるため、他のスレッドがそれを読み込んでいます。 –

+3

OPはストリームではなくファイル記述子を使用して読み込みます。ストリームバッファはありません(自分で実装していない場合)。たとえあったとしても、バッファが空であることは、読み込み可能なデータがないことと同じではありません。 –

関連する問題