summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/dl/cptr.c13
-rw-r--r--ext/dl/lib/dl/import.rb32
-rw-r--r--ext/dl/test/test_import.rb5
3 files changed, 50 insertions, 0 deletions
diff --git a/ext/dl/cptr.c b/ext/dl/cptr.c
index 27be637a5a..88897ccc86 100644
--- a/ext/dl/cptr.c
+++ b/ext/dl/cptr.c
@@ -10,6 +10,8 @@
VALUE rb_cDLCPtr;
+static ID id_to_ptr;
+
static void
dlptr_free(struct ptr_data *data)
{
@@ -422,6 +424,15 @@ rb_dlptr_s_to_ptr(VALUE self, VALUE val)
#endif
return rb_dlptr_new(fp, sizeof(FILE), NULL);
}
+ else if( rb_respond_to(val, id_to_ptr) ){
+ VALUE vptr = rb_funcall(val, id_to_ptr, 0);
+ if( rb_obj_is_kind_of(vptr, rb_cDLCPtr) ){
+ return vptr;
+ }
+ else{
+ rb_raise(rb_eDLError, "to_ptr should return a CPtr object.");
+ }
+ }
else{
return rb_dlptr_new(NUM2PTR(rb_Integer(val)), 0, NULL);
}
@@ -430,6 +441,8 @@ rb_dlptr_s_to_ptr(VALUE self, VALUE val)
void
Init_dlptr()
{
+ id_to_ptr = rb_intern("to_ptr");
+
rb_cDLCPtr = rb_define_class_under(rb_mDL, "CPtr", rb_cObject);
rb_define_alloc_func(rb_cDLCPtr, rb_dlptr_s_allocate);
rb_define_singleton_method(rb_cDLCPtr, "malloc", rb_dlptr_s_malloc, -1);
diff --git a/ext/dl/lib/dl/import.rb b/ext/dl/lib/dl/import.rb
index 2f21e9195c..2ad805598a 100644
--- a/ext/dl/lib/dl/import.rb
+++ b/ext/dl/lib/dl/import.rb
@@ -62,6 +62,38 @@ module DL
@type_alias[alias_type] = orig_type
end
+ def sizeof(ty)
+ case ty
+ when String
+ ty = parse_ctype(ty, @type_alias).abs()
+ case ty
+ when TYPE_CHAR
+ return SIZEOF_CHAR
+ when TYPE_SHORT
+ return SIZEOF_SHORT
+ when TYPE_INT
+ return SIZEOF_INT
+ when TYPE_LONG
+ return SIZEOF_LONG
+ when TYPE_LONG_LONG
+ return SIZEOF_LONG_LON
+ when TYPE_FLOAT
+ return SIZEOF_FLOAT
+ when TYPE_DOUBLE
+ return SIZEOF_DOUBLE
+ when TYPE_VOIDP
+ return SIZEOF_VOIDP
+ else
+ raise(DLError, "unknown type: #{ty}")
+ end
+ when Class
+ if( ty.instance_methods().include?("to_ptr") )
+ return ty.size()
+ end
+ end
+ return CPtr[ty].size()
+ end
+
def parse_bind_options(opts)
h = {}
prekey = nil
diff --git a/ext/dl/test/test_import.rb b/ext/dl/test/test_import.rb
index ced2ac8dd7..14fb1eba65 100644
--- a/ext/dl/test/test_import.rb
+++ b/ext/dl/test/test_import.rb
@@ -40,6 +40,11 @@ module DL
end
class TestImport < TestBase
+ def test_sizeof()
+ assert_equal(DL::SIZEOF_VOIDP, LIBC.sizeof("FILE*"))
+ assert_equal(LIBC::MyStruct.size(), LIBC.sizeof(LIBC::MyStruct))
+ end
+
def test_unsigned_result()
d = (2 ** 31) + 1