Ruby で IO#ioctl の引数に構造体 (struct) へのポインタを渡したいとき
ioctl に構造体のポインタを渡して値を返してもらうような場合があると思います。
このような場合、文字列つくってそのまま渡せば struct のポインタになるようでした。
つまり pack/unpack("P") を使ってこう書くのは
Termios2::FORMAT = "I!I!I!I!CC19I!I!"
Termios2::FORMAT_POINTER = "P44"
# バッファ
v = tio.values.flatten.pack(Termios2::FORMAT)
# pack("P") でポインタを取得
pointer = [v].pack(Termios2::FORMAT_POINTER)
# ポインタを数値として渡す
self.ioctl(TCGETS2, pointer.unpack("L!")[0])
# unpack("P") でポインタから値を取得し、構造体を unpack
tio = Termios2.new(*pointer.unpack(Termios2::FORMAT_POINTER)[0].unpack(Termios2::FORMAT)) 単に文字列を引数に渡す方法で簡単に書ける
# バッファ
v = tio.values.flatten.pack(Termios2::FORMAT)
self.ioctl(TCGETS2, v) # v が ioctl 内で書き変わる
tio = Termios2.new(*v.unpack(Termios2::FORMAT)) v の長さが構造のサイズに足りてないと死にます
備考
リファレンスの IO#ioctl には以下のように書いてあるんだけど、意味がわからなかった……
If it is a string, it is interpreted as a binary sequence of bytes.
関連エントリー
- ruby-serialport で任意のボーレートを設定するには (ただし Linux に限る) ruby serialport は、このあたりで設定できるボーレートを列挙していて、これら以外のボーレートを設定できないようです (unkn...
- Ruby でネストした構造体文字列をネストした配列として unpack する Cの構造体とかだと、構造体の中に他の構造体ということは普通にあります。 こういった構造体の文字列を unpack すると、全部フラットな配列...
- スマートメータから瞬間消費電力を読むRubyのコード スマートメータのBルートサービスで Wi-SUN モジュールを使って瞬間消費電力を読み出す | tech - 氾濫原 にひき続き Wi-SU...
- Linux 上の LL で I2C する (Ruby) なんとなく i2c-dev.h とかで定義されているAPIを呼ばないと使えないのかなあと思っていたけど、デバイスファイルの読み書きと ioc...
- Rock64 を買って golang で赤外線受信を試してみた Rock64 http://akizukidenshi.com/catalog/g/gM-12382/ というのを買ってみた。 とりあえず ...