概要
RubyInline を使います
他にも Rice や FFI といったライブラリもありますが今回は RubyInline を使います
環境
- macOS 10.14.1
- clang Apple LLVM version 10.0.0 (clang-1000.11.45.5)
- Ruby 2.5.1p57
インストール
- bundle init
- vim Gemfile
gem "RubyInline"
bundle install --path vendor
gem の名前に注意しましょう
inline
ではありません
Hello World
とりあえず printf
でメッセージを表示するサンプルを書いてみましょう
- vim test.rb
require 'inline'
class Test
inline(:C) do |builder|
builder.include '<stdio.h>'
builder.c '
void say(char *msg) {
printf("%s\n", msg);
}
'
end
end
t = Test.new
t.say "hello"
- bundle exec ruby test.rb
で「hello」と表示されます
builder を使ってヘッダファイルの読み込み (.include
) や C言語の関数を登録 (.c
) します
Ruby から参照する場合はクラスを作成して、そのクラスのメソッドとして呼び出します
Ruby の文字列は char のポインタで普通に渡せました
返り値がある場合
require 'inline'
class Test
inline(:C) do |builder|
builder.include '<stdio.h>'
builder.c '
int sum(int a, int b) {
return a + b;
}
'
end
end
t = Test.new
ret = t.sum 1, 2
puts ret.class
puts ret
int は Ruby 側では Integer として扱われました
複数の include
require 'inline'
class Test
inline(:C) do |builder|
builder.include '<stdio.h>'
builder.include '<math.h>'
builder.c '
double my_pow(double a, double b) {
printf("%lf\n", a);
printf("%lf\n", b);
return pow(a, b);
}
'
end
end
t = Test.new
ret = t.my_pow 10, 2
puts ret.class
puts ret
単純に 2 度 .include
をコールすれば OK です
ちなみに C言語の double は Ruby では Float でした
最後に
Ruby から C 言語をコールしてみました
もし C の共有ライブラリ (.so
形式) などでしか作られていない場合は使えるかなと思います
あとは RubyInline を使う理由に C で処理したほうが早いという理由もありあした
C 以外に C++ も使えるのでたしかに速度重視の場合は考慮してもいいかもしれません
0 件のコメント:
コメントを投稿