summaryrefslogtreecommitdiff
path: root/ext/ffi_c
diff options
context:
space:
mode:
authorLars Kanis <lars@greiz-reinsdorf.de>2023-04-21 08:34:07 +0200
committerLars Kanis <lars@greiz-reinsdorf.de>2023-04-27 13:47:57 +0200
commite987ab50366a4b08617a20568eabdaa1fb761317 (patch)
tree0f10e6887c41ae27c0514ddd7c5b0d1b55a4f8ea /ext/ffi_c
parentad1a2e0cd5970e5d1618782a6ac2d5328811370d (diff)
downloadffi-e987ab50366a4b08617a20568eabdaa1fb761317.tar.gz
Add the possibility to query attached funtions and variables
Diffstat (limited to 'ext/ffi_c')
-rw-r--r--ext/ffi_c/Function.c21
-rw-r--r--ext/ffi_c/MappedType.c10
-rw-r--r--ext/ffi_c/Variadic.c9
3 files changed, 37 insertions, 3 deletions
diff --git a/ext/ffi_c/Function.c b/ext/ffi_c/Function.c
index f88bc93..40d613e 100644
--- a/ext/ffi_c/Function.c
+++ b/ext/ffi_c/Function.c
@@ -492,8 +492,8 @@ static VALUE
function_attach(VALUE self, VALUE module, VALUE name)
{
Function* fn;
- char var[1024];
+ StringValue(name);
TypedData_Get_Struct(self, Function, &function_data_type, fn);
if (fn->info->parameterCount == -1) {
@@ -513,8 +513,12 @@ function_attach(VALUE self, VALUE module, VALUE name)
/*
* Stash the Function in a module variable so it does not get garbage collected
*/
- snprintf(var, sizeof(var), "@@%s", StringValueCStr(name));
- rb_cv_set(module, var, self);
+ VALUE funcs = rb_iv_get(module, "@ffi_functions");
+ if (RB_NIL_P(funcs)) {
+ funcs = rb_hash_new();
+ rb_iv_set(module, "@ffi_functions", funcs);
+ }
+ rb_hash_aset(funcs, name, self);
rb_define_singleton_method(module, StringValueCStr(name),
rbffi_MethodHandle_CodeAddress(fn->methodHandle), -1);
@@ -555,6 +559,16 @@ function_autorelease_p(VALUE self)
return fn->autorelease ? Qtrue : Qfalse;
}
+static VALUE
+function_type(VALUE self)
+{
+ Function* fn;
+
+ TypedData_Get_Struct(self, Function, &function_data_type, fn);
+
+ return fn->rbFunctionInfo;
+}
+
/*
* call-seq: free
* @return [self]
@@ -1027,6 +1041,7 @@ rbffi_Function_Init(VALUE moduleFFI)
rb_define_method(rbffi_FunctionClass, "attach", function_attach, 2);
rb_define_method(rbffi_FunctionClass, "free", function_release, 0);
rb_define_method(rbffi_FunctionClass, "autorelease=", function_set_autorelease, 1);
+ rb_define_private_method(rbffi_FunctionClass, "type", function_type, 0);
/*
* call-seq: autorelease
* @return [Boolean]
diff --git a/ext/ffi_c/MappedType.c b/ext/ffi_c/MappedType.c
index e61af30..20b14e9 100644
--- a/ext/ffi_c/MappedType.c
+++ b/ext/ffi_c/MappedType.c
@@ -175,6 +175,15 @@ mapped_from_native(int argc, VALUE* argv, VALUE self)
return rb_funcall2(m->rbConverter, id_from_native, argc, argv);
}
+static VALUE
+mapped_converter(VALUE self)
+{
+ MappedType*m = NULL;
+ TypedData_Get_Struct(self, MappedType, &mapped_type_data_type, m);
+
+ return m->rbConverter;
+}
+
void
rbffi_MappedType_Init(VALUE moduleFFI)
{
@@ -195,5 +204,6 @@ rbffi_MappedType_Init(VALUE moduleFFI)
rb_define_method(rbffi_MappedTypeClass, "native_type", mapped_native_type, 0);
rb_define_method(rbffi_MappedTypeClass, "to_native", mapped_to_native, -1);
rb_define_method(rbffi_MappedTypeClass, "from_native", mapped_from_native, -1);
+ rb_define_method(rbffi_MappedTypeClass, "converter", mapped_converter, 0);
}
diff --git a/ext/ffi_c/Variadic.c b/ext/ffi_c/Variadic.c
index 2e9d790..fb37194 100644
--- a/ext/ffi_c/Variadic.c
+++ b/ext/ffi_c/Variadic.c
@@ -318,6 +318,14 @@ variadic_invoke(VALUE self, VALUE parameterTypes, VALUE parameterValues)
return rbffi_NativeValue_ToRuby(invoker->returnType, invoker->rbReturnType, retval);
}
+static VALUE
+variadic_result_type(VALUE self)
+{
+ VariadicInvoker* invoker;
+
+ TypedData_Get_Struct(self, VariadicInvoker, &variadic_data_type, invoker);
+ return invoker->rbReturnType;
+}
void
rbffi_Variadic_Init(VALUE moduleFFI)
@@ -329,5 +337,6 @@ rbffi_Variadic_Init(VALUE moduleFFI)
rb_define_method(classVariadicInvoker, "initialize", variadic_initialize, 4);
rb_define_method(classVariadicInvoker, "invoke", variadic_invoke, 2);
+ rb_define_method(classVariadicInvoker, "result_type", variadic_result_type, 0);
}