aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--ext/dl/dl.h1
-rw-r--r--ext/dl/lib/dl/func.rb6
-rw-r--r--ext/dl/lib/dl/value.rb13
-rw-r--r--ext/dl/method.c (renamed from ext/dl/function.c)47
-rw-r--r--test/dl/test_method.rb11
6 files changed, 49 insertions, 33 deletions
diff --git a/ChangeLog b/ChangeLog
index acc21167db..c809edc0e6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+Tue Feb 16 11:03:19 2010 Aaron Patterson <aaron@tenderlovemaking.com>
+
+ * ext/dl/method.c: Adding DL::Method as a superclass for DL::Function
+
Mon Feb 15 23:37:30 2010 Tanaka Akira <akr@fsij.org>
* io.c: check lseek error by errno. NetBSD 4.0.1 may return -1 as
diff --git a/ext/dl/dl.h b/ext/dl/dl.h
index da5695d3fa..81c8ee3bd9 100644
--- a/ext/dl/dl.h
+++ b/ext/dl/dl.h
@@ -136,6 +136,7 @@
extern VALUE rb_mDL;
extern VALUE rb_cDLHandle;
+extern VALUE rb_cDLCPtr;
extern VALUE rb_cDLSymbol;
extern VALUE rb_eDLError;
extern VALUE rb_eDLTypeError;
diff --git a/ext/dl/lib/dl/func.rb b/ext/dl/lib/dl/func.rb
index 0ee2df1f23..c5a2dda355 100644
--- a/ext/dl/lib/dl/func.rb
+++ b/ext/dl/lib/dl/func.rb
@@ -6,7 +6,7 @@ require 'dl/value'
require 'thread'
module DL
- class Function
+ class Function < DL::Method
include DL
include ValueUtil
@@ -20,7 +20,7 @@ module DL
end
@args = argtypes
- native_init(@args.reject { |x| x == TYPE_VOID }, cfunc.ctype, abi)
+ super(@cfunc, @args.reject { |x| x == TYPE_VOID }, cfunc.ctype, abi)
end
def to_i()
@@ -35,7 +35,7 @@ module DL
if block_given?
args.find { |a| DL::Function === a }.bind_at_call(&block)
end
- native_call(*args)
+ super
end
def wrap_result(r)
diff --git a/ext/dl/lib/dl/value.rb b/ext/dl/lib/dl/value.rb
index c613afe5cf..cc6da6a7fb 100644
--- a/ext/dl/lib/dl/value.rb
+++ b/ext/dl/lib/dl/value.rb
@@ -36,19 +36,6 @@ module DL
end
end
- def ruby2ffi arg, type
- return arg unless type == TYPE_VOIDP
- case arg
- when nil
- 0
- when CPtr
- arg.to_i
- else
- CPtr[arg].to_i
- end
- end
- private :ruby2ffi
-
def wrap_arg(arg, ty, funcs = [], &block)
funcs ||= []
case arg
diff --git a/ext/dl/function.c b/ext/dl/method.c
index 377d2fe054..8462292d98 100644
--- a/ext/dl/function.c
+++ b/ext/dl/method.c
@@ -7,7 +7,7 @@
#include "dl.h"
#include <dl_conversions.h>
-VALUE rb_cDLFunction;
+VALUE rb_cDLMethod;
typedef union
{
@@ -49,7 +49,7 @@ dlfunction_memsize(const void *p)
}
const rb_data_type_t dlfunction_data_type = {
- "dl/function",
+ "dl/method",
0, dlfunction_free, dlfunction_memsize,
};
@@ -62,13 +62,22 @@ rb_dlfunc_allocate(VALUE klass)
}
static VALUE
-rb_dlfunction_native_init(VALUE self, VALUE args, VALUE ret_type, VALUE abi)
+rb_dlfunction_initialize(int argc, VALUE argv[], VALUE self)
{
ffi_cif * cif;
ffi_type **arg_types;
ffi_status result;
+ VALUE ptr, args, ret_type, abi;
int i;
+ rb_scan_args(argc, argv, "31", &ptr, &args, &ret_type, &abi);
+ if(NIL_P(abi)) abi = INT2NUM(FFI_DEFAULT_ABI);
+
+ rb_iv_set(self, "@ptr", ptr);
+ rb_iv_set(self, "@args", args);
+ rb_iv_set(self, "@return_type", ret_type);
+ rb_iv_set(self, "@abi", abi);
+
TypedData_Get_Struct(self, ffi_cif, &dlfunction_data_type, cif);
arg_types = xcalloc(RARRAY_LEN(args) + 1, sizeof(ffi_type *));
@@ -188,17 +197,21 @@ rb_dlfunction_call(int argc, VALUE argv[], VALUE self)
values = xcalloc((size_t)argc + 1, (size_t)sizeof(void *));
generic_args = xcalloc((size_t)argc, (size_t)sizeof(dl_generic));
- cfunc = rb_iv_get(self, "@cfunc");
+ cfunc = rb_iv_get(self, "@ptr");
types = rb_iv_get(self, "@args");
for (i = 0; i < argc; i++) {
VALUE dl_type = RARRAY_PTR(types)[i];
- VALUE src = rb_funcall(self,
- rb_intern("ruby2ffi"),
- 2,
- argv[i],
- dl_type
- );
+ VALUE src = argv[i];
+
+ if(NUM2INT(dl_type) == DLTYPE_VOIDP) {
+ if(NIL_P(src)) {
+ src = INT2NUM(0);
+ } else if(rb_cDLCPtr != CLASS_OF(src)) {
+ src = rb_funcall(rb_cDLCPtr, rb_intern("[]"), 1, src);
+ }
+ src = rb_Integer(src);
+ }
dl2generic(NUM2INT(dl_type), src, &generic_args[i]);
values[i] = (void *)&generic_args[i];
@@ -215,24 +228,24 @@ rb_dlfunction_call(int argc, VALUE argv[], VALUE self)
xfree(values);
xfree(generic_args);
- return unwrap_ffi(rb_funcall(cfunc, rb_intern("ctype"), 0), retval);
+ return unwrap_ffi(rb_iv_get(self, "@return_type"), retval);
}
void
Init_dlfunction(void)
{
- rb_cDLFunction = rb_define_class_under(rb_mDL, "Function", rb_cObject);
+ rb_cDLMethod = rb_define_class_under(rb_mDL, "Method", rb_cObject);
- rb_define_const(rb_cDLFunction, "DEFAULT", INT2NUM(FFI_DEFAULT_ABI));
+ rb_define_const(rb_cDLMethod, "DEFAULT", INT2NUM(FFI_DEFAULT_ABI));
#ifdef FFI_STDCALL
- rb_define_const(rb_cDLFunction, "STDCALL", INT2NUM(FFI_STDCALL));
+ rb_define_const(rb_cDLMethod, "STDCALL", INT2NUM(FFI_STDCALL));
#endif
- rb_define_alloc_func(rb_cDLFunction, rb_dlfunc_allocate);
+ rb_define_alloc_func(rb_cDLMethod, rb_dlfunc_allocate);
- rb_define_private_method(rb_cDLFunction, "native_call", rb_dlfunction_call, -1);
+ rb_define_method(rb_cDLMethod, "call", rb_dlfunction_call, -1);
- rb_define_private_method(rb_cDLFunction, "native_init", rb_dlfunction_native_init, 3);
+ rb_define_method(rb_cDLMethod, "initialize", rb_dlfunction_initialize, -1);
}
/* vim: set noet sw=4 sts=4 */
diff --git a/test/dl/test_method.rb b/test/dl/test_method.rb
new file mode 100644
index 0000000000..e1ed5ed88b
--- /dev/null
+++ b/test/dl/test_method.rb
@@ -0,0 +1,11 @@
+require_relative 'test_base'
+require 'dl/func'
+
+module DL
+ class TestMethod < TestBase
+ def test_method_call
+ f = Method.new(@libc['sinf'], [TYPE_FLOAT], TYPE_FLOAT)
+ assert_in_delta 1.0, f.call(90 * Math::PI / 180), 0.0001
+ end
+ end
+end