4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

CのヘッダーファイルからRuby-FFIのコードを自動生成するc2ffi4rbをリバイバルした

Last updated at Posted at 2023-09-27

はじめに

Rubyは、PythonやJavaScriptのような人気言語と比較すると利用人口が少ないため、やりたいことを実現するためには、C言語やRust言語など、他言語で書かれたライブラリのバインディングを適宜自作する必要があります。

Ruby言語では、バインディング作成のための仕組みが数多く用意されています。

  • ネイティブC拡張
  • fiddle
  • ruby-ffi
  • GObject Introspection
  • Magnus(Rust用)

swig というのもありますが、私は使用経験がありません。

この中で「個人用のバインディングの作成時間の最小化」という観点から評価すると ruby-ffi が最もよいと思います。ruby-ffiは、Cの型とRubyのクラスを自動で相互変換してくれ、構造体に対するサポートも豊富です。

しかし、ruby-ffiを選択する場合でも、バインディング作成の敷居は低くはありません。私も読者もフルタイムでRubyのライブラリを作れるわけではありません。最初の数時間でプロトタイプが完成する、ぐらいの工数でないと、なかなか隙間時間でバインディングを作成していくのは難しいと思います。

現実的には

  1. Cのソースコードからコメントを消す
  2. 正規表現を用いたコードの置換
  3. diff を利用したC関数とRubyのメソッドの比較確認

などの泥臭い方法により、バインディング作成の時短を図ることになると思います。

c2ffi

そんなときに少し便利なのがc2ffiというツールです。このツールは Cのヘッダーファイルをパースして jsonファイルを生成します 。バインディング作成者にとっては、テキストエディタの置換機能とならび、神ツールといってもよいでしょう。(このツールはバインディングの自動生成だけではなく、diffを利用したCヘッダーとRubyメソッドの比較確認にも使えます。)

しかし、神ツールにも欠点はあります。このツールはllvmをライブラリと使用していて、インストールが一筋縄ではいきません。個人的には、コンパイルできない理由を追究するスキルがない時間がもったいないので、docker環境を用意してビルドしたりしています。macの場合は、issueにビルドできないという報告がありますので、それに基づいてソースコードを少し修正する必要があります。

c2ffi4rb

c2ffiは当初はRubyのバインディングの生成も念頭に作られたらしく、c2ffi-ruby というツールがありました。

しかし、これは10年前のツールで一度作られたきりメンテナンスされていません。gemにもなっておらず、コマンドラインツールとしてのインストールも面倒でした。そこで、これをGem化して c2ffi4rb という名前をつけて、簡単にインストールできるようにしました。

使い方

c2ffiを使って、ヘッダーファイルからjsonファイルを生成します。

c2ffi -M macros.h -o example.json example.h
c2ffi -o macros.json macros.h

c2ffi4rb を用いて、バインディングの原型を作ります。

c2ffi4rb example.json macro.json > simple.rb

このツールは完璧とは言えませんが、基本的な機能は備えています。
少しずつ改善・修正していくつもりです。

この記事は以上です。

4
1
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
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?