RubyのMemoryView入門(4)
前
データを使う側(ConstIntViewer)を実装する。
code:ext/learning_memory_view/learning_memory_view.c
VALUE cConstInteViewer;
// ...
static VALUE
const_int_viewer_initialize(VALUE self, VALUE memory_view)
{
rb_iv_set(self, "memory_view", memory_view);
return Qnil;
}
static VALUE
const_int_viewer_get_data(VALUE self)
{
VALUE memory_view = rb_iv_get(self, "memory_view");
rb_memory_view_t view;
if (!rb_memory_view_available_p(memory_view)) {
rb_raise(rb_eRuntimeError, "memory view is not available");
}
if (!rb_memory_view_get(memory_view, &view, RUBY_MEMORY_VIEW_SIMPLE)) {
rb_raise(rb_eRuntimeError, "failed to get memory view");
}
VALUE rv = rb_ary_new2(1);
int *data = (int *)view.data; /* Use format instead of casting? */
for (int i = 0; i < view.byte_size / view.item_size; i++) {
rb_ary_push(rv, INT2NUM((int)datai)); /* Use format instead of casting? */ }
return rv;
}
// ...
void
Init_learning_memory_view(void)
{
VALUE mod = rb_define_module("LearningMemoryView");
// ...
cConstInteViewer = rb_define_class_under(mod, "ConstIntViewer", rb_cObject);
rb_define_method(cConstInteViewer, "initialize", const_int_viewer_initialize, 1);
rb_define_method(cConstInteViewer, "data", const_int_viewer_get_data, 0);
}
code:test/test_learning_memory_view.rb
require "test/unit"
require "fiddle"
require "learning_memory_view"
class TestLearningMemoryView < Test::Unit::TestCase
include LearningMemoryView
def test_initialize
assert_instance_of FloatArray, FloatArray.new
end
class TestConstInt < self
def test_const_int
const_int = ConstInt.new
Fiddle::MemoryView.export const_int do |memory_view|
assert_equal 4, memory_view.item_size
assert_equal 4, memory_view.byte_size
assert_equal "l*", memory_view.format
assert_equal 3, memory_view.to_s.unpack(memory_view.format) end
end
def test_const_int_viewer
const_int = ConstInt.new
viewer = ConstIntViewer.new(const_int)
assert_equal 3, viewer.data end
end
end
受け取る型をConstIntクラスに固定しているからシンプルだが、多分、元のMemoryViewの情報を色々調べて適切なデータ型として処理する必要があるんだと思う。
次