LoginSignup
3
3

More than 5 years have passed since last update.

RustでLinuxのinput eventをダンプする (bindgen使用)

Last updated at Posted at 2018-10-02

bindgenを使ってみた。

Linuxのinput event

input event はキーボードやマウス、タッチスクリーンなどのイベントです。
このページがわかりやすい。
Linux Input Subsystemの使い方
このページの最初のサンプルの「音量調整プログラム」と似たものをRustで書いてみました。

bindgen

bindgenはCのヘッダファイルを読んで、そのストラクチャや定数、関数の宣言をRustの形式に変換してくれます。
bindgen users guide

bindgenの準備

sudo apt install clang
cargo install bindgen

ヘッダファイルを変換する

bindgen users guide のチュートリアルでは、build.rsを作ってcargoでビルドするときにヘッダファイルの変換をするようにしていますが、ここでは手っ取り早くbindgenコマンドを手で実行してみます。

$ bindgen /usr/include/linux/input.h -o src/input.rs
Custom { kind: Other, error: StringError("Internal rustfmt error") }

むむ、何かエラーになった。
でもファイルはできているようなので深入りせずにこのまま進みます。(rustc は1.29.1 を使用)

サンプルプログラム

gistに貼りました。ここ

デバイスファイルからストラクチャのサイズ分を読んで、キャストする部分は以下の通り。

fn read_input_event(f: &mut File) -> io::Result<(input_event)> {
    const sz: usize = std::mem::size_of::<input_event>();
    let mut buf = [0; sz];
    f.read_exact(&mut buf)?;
    let ie: input_event = unsafe { std::mem::transmute(buf) };
    Ok(ie)
}

つまずいたところ

最初にclangをインストールするのを忘れていた。bindgenは実行できるけど、stddef.hが見つからないという不思議な挙動になった。

input_event のストラクチャにはtype という名のメンバがあった。これはRustの予約語と重なるので、変換して出力されたファイルでは type_ に変更されていた。

定数のdefine値は全てu32として生成される。ストラクチャのメンバがu16で、Rustは型に厳しいので明示的なキャストが必要だった。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3