$ sudo gem install ZenTest hoe rake-compiler $ sow stree require "test/unit" require "stree" class TestStree < Test::Unit::TestCase def test_hello_world assert_equal 'hello world', Stree.hello_world end end $ tree . |-- CHANGELOG.rdoc |-- Manifest.txt |-- README.rdoc |-- Rakefile |-- ext | `-- stree |-- lib | `-- stree.rb `-- test `-- test_stree.rb require 'rubygems' require 'hoe' Hoe.spec 'str
RHGの逆襲で「st_tableを拡張で使うと便利だよ」という話を聞いて、へーと思ったので、st_tableで簡単なハッシュテーブルを実装してみた。 拡張ライブラリ #ifdef _WIN32 __declspec(dllexport) void Init_my_hash(void); #endif #include "ruby.h" #include "st.h" static void my_hash_free(st_table *table) { st_free_table(table); } static VALUE my_hash_alloc(VALUE klass) { st_table *table = st_init_strtable(); return Data_Wrap_Struct(klass, 0, -1, table); } static VALUE my_has
One of the most interesting design challenges in a programming language interpreter or VM is what kind of memory management API to offer to native extensions. This issue is more or less invisible unless you’re writing a native extension. When you are simply writing a program in Ruby, Python, Lua, etc., you don’t usually care how the memory management is implemented. You only care is that you can c
This is the fifth in my series of posts about writing ruby extensions in C. The first post talked about the basic structure of a project, including how to set up building. The second post talked about generating documentation. The third post talked about initializing the module and setting up classes. The fourth post talked about types and return values. This post will focus on creating and handli
世間の皆々様に至ってはきっと日々ruby拡張を作ったりしてることと思います。 わたしはなんかRuby/SDL使った画像ビューアを作ったりしてました。その適当な画像ビューアはまあどうでもいいんですけど、書いててふと「あれこれRuby/SDLが確保したSDL資源(Surfaceとか)どこで解放してんの?」と思ってソース読んだらGC呼ばれるときちゃんと一緒に解放されるようなので、うんよくできてるなーと思いました。 というわけでその理解が合っているのか、ruby拡張で自前のアロケータとフリーするminimalなコードのテストをしてみんとす。 mystruct.c #include "ruby.h" typedef struct { int dummy; } MyStruct; static VALUE cStruct = Qnil; static void myfree(MyStruct *buf
はじめに 表題のとおりでよく考えれば当たり前なのですが、ちょっとハマったので書いておきます。 要約すると、Rubyの拡張ライブラリを作る場合、用意されているALLOC()などのメモリ確保マクロを使わないときには、ちゃんと自分でGCを呼ぶ必要がある、という話です。 環境 Ruby 1.9.2p180 (2011-02-18) [i686-linux] 本題 こんなライブラリがあったとして // foo_lib.hpp #include <stdlib.h> typedef struct Foo { double bar[1000000]; } Foo; Foo* create_foo() { Foo* foo = (Foo*)malloc(sizeof(Foo)); if (foo == NULL) throw "<Memory allocation failed>"; return foo
その他に内部で利用されている以下のタイプがあります. T_ICLASS T_MATCH T_UNDEF T_NODE T_ZOMBIE ほとんどのタイプはCの構造体で実装されています. VALUEのデータタイプをチェックする ruby.hではTYPE()というマクロが定義されていて,VALUEのデータ タイプを知ることが出来ます.TYPE()マクロは上で紹介したT_XXXX の形式の定数を返します.VALUEのデータタイプに応じて処理する 場合には,TYPE()の値で分岐することになります. switch (TYPE(obj)) { case T_FIXNUM: /* FIXNUMの処理 */ break; case T_STRING: /* 文字列の処理 */ break; case T_ARRAY: /* 配列の処理 */ break; default: /* 例外を発生させる */
ruby-opencvは一応Windowsもサポートしているわけですが、いつからかOpenCVがMinGW版のバイナリを配布しなくなってしまったため、RubyInstallerを使っている場合は自前でOpenCVをビルドしなければならない状態になっていました。 GitHubでもissueがいくつか挙がってたのをずーっと放置していたのですが、さすがに放置し過ぎな気がしてきたので、取り急ぎインストール用のドキュメントを作成しました。 ruby-opencv/install-ruby-opencv-with-rubyinstaller-on-windows.md at master · ruby-opencv/ruby-opencv · GitHub 大雑把に言うと、ポイントは以下の2点です。 DevKitのビルドツール(mingw-32-make、gcc、g++)を使ってOpenCVをビルドす
DXRubyの描画予約順ソートはマージソートを採用している。初期の頃はシンプルなバブルソートだったのだが、さすがにアレなのでマージソートに変更したのだ。なぜマージソートを選択したのかというと、描画優先順が同一だった場合、メソッドを発行した順に描画される必要があるからソートは安定ソートであるのがまず前提で、それなりに速く、実行時間の変動が少ないからだ。 1フレームという規定時間内に処理が完了する必要がある場合、ある処理の実行時間が想定できないと手痛いことになる。最も遅い時間にあわせて他を切り詰めないといけなくなるからだ。ソートの場合、データの並び方のパターンで実行時間が大きく変わってくる方式が多いから、そういうのを採用すると速いときは速いが遅いときは遅い、しかも並び方のパターンによるから微妙に予測ができない、ということになる。ソートアルゴリズムまで考えたうえでソートが速くなるように描画順を考
Ruby2.1.0-preview1は出たがREADME.EXT.jaを見ても書いてないので調べたことをここに書いておく。正式なマニュアルじゃないし検証してるわけでもないから豪快に間違っているかもしれん。 ■はじめに RGenGCは今までの拡張ライブラリのコードそのままで動作するように作られていて、何も考えずにコンパイルすれば普通に動く。2.1用に拡張ライブラリをコンパイルして動かない場合、よっぽど特殊なことをしていない限りはRGenGC以外のところに原因があると考えてよい。そのぐらい互換性に気を使われている。 なので特別に対応する必要は無いのだが、対応すればGCのパフォーマンスが上がるし、Shady化の処理を省く効果もあったりしてさらに速くなるかもしれない。速度を売りにした拡張ライブラリは対応しておいて損は無いだろう。 RGenGCの対応には大きくわけて以下の2つのパターンがある。両方や
Ruby の拡張ライブラリを書く時には、Ruby の処理を呼び出すと例外が発生する可能性があることに気をつけないといけません。たとえば以下のように some_func という関数を呼び出す wrapper method を定義したとします。 extern int some_func(int len, int *ary); VALUE sample_func(VALUE self, VALUE arg) { int *buf; int len, i, result; if (!RB_TYPE_P(arg, T_ARRAY)) rb_raise(rb_eArgError, "arg must be an Array"); len = RARRAY_LEN(arg); buf = ALLOC_N(int, len); for (i = 0; i < len; i++) { buf[i] = NU
RubyからC++のクラスを呼び出す例をまとめる。環境は以下の通り。 Fedora7 g++ 4.1.2 SWIG 1.3.31 Ruby 1.8.6 ANTLR(2.7.7)で生成されたC++によるパーサプログラムを、Rubyから呼び出すために調べたものをまとめてみた。ANTLRも3.0からはRubyも対象言語に含まれているので、わざわざC++のクラスを呼び出すこともなくなるだろう。 クラス定義 まず、C++のクラス定義から。 クラスExmapleのヘッダファイルと定義ファイルを用意する。 Exaple.hpp // Example.hpp #ifndef __Example_hpp #define __Example_hpp class Example { public: Example(void); ~Example(void); char* toUpper(char* str);
_ HAVE_NATIVETHREAD 1.8.7-p299にしたらvrswinのmakeが失敗した。 1.9対応の定義が有効になって1.8では未定義の定数(RUBY_UBF_IO 多分、unblock functionの頭語で、グローバルロックを解除可能な待ち状態に入る場合に指定する)を参照したからだ。 とりあえずその定数を&& !defindしてしのいだ。 が、HAVE_NATIVETHREADでは1.8と1.9が区別できないので、RUBY_UBF_IOを見たほうが意図的にも良さそうに思う。 diff -u -p swin.c~ swin.c *** swin.c~ Sat Feb 07 23:52:50 2009 --- swin.c Sat Jun 26 22:35:02 2010 *************** swin_call_threadblocking(DWORD chk
拡張ライブラリ作成 ruby.hをincludeし、Ruby拡張ライブラリを作成するためのマクロ、タイプを使用できるようにする。 ruby.hは、ruby-devをインストールしなければ使えない。 作成したCソースのビルド ・extconf.rbを記述 ・extconf.rbを実行しMakefileを作成 ・作成されたMakefileを使用しmakeする C構造体をRuby側で扱えるようにするには、 VALUE Data_Wrap_Struct(VALUE klass, RUBY_DATA_FUNC mark, RUBY_DATA_FUNC free, void *sval) で構造体をラッピングして、 void Data_Get_Struct(VALUE obj, type, type *svar) で取り出すようにする。 ■Data_Get_Struct(VALUE obj, type
リリース、障害情報などのサービスのお知らせ
最新の人気エントリーの配信
処理を実行中です
j次のブックマーク
k前のブックマーク
lあとで読む
eコメント一覧を開く
oページを開く