ruby-changes:66252
From: Sutou <ko1@a...>
Date: Tue, 18 May 2021 12:49:05 +0900 (JST)
Subject: [ruby-changes:66252] 881b2dc898 (master): [ruby/fiddle] closuRe: add support for const char *
https://git.ruby-lang.org/ruby.git/commit/?id=881b2dc898 From 881b2dc89865c1b7a7fbc2c89e13789a068f335d Mon Sep 17 00:00:00 2001 From: Sutou Kouhei <kou@c...> Date: Fri, 25 Dec 2020 06:02:19 +0900 Subject: [ruby/fiddle] closure: add support for const char * GitHub: fix GH-62 Reported by Cody Krieger. Thanks!!! https://github.com/ruby/fiddle/commit/284b820f2d --- ext/fiddle/closure.c | 8 ++++++++ test/fiddle/test_closure.rb | 13 +++++++++++++ 2 files changed, 21 insertions(+) diff --git a/ext/fiddle/closure.c b/ext/fiddle/closure.c index fc29655..3679e5c 100644 --- a/ext/fiddle/closure.c +++ b/ext/fiddle/closure.c @@ -130,6 +130,10 @@ with_gvl_callback(void *ptr) https://github.com/ruby/ruby/blob/trunk/ext/fiddle/closure.c#L130 rb_ary_push(params, ULL2NUM(*(unsigned LONG_LONG *)x->args[i])); break; #endif + case TYPE_CONST_STRING: + rb_ary_push(params, + rb_str_new_cstr(*((const char **)(x->args[i])))); + break; default: rb_raise(rb_eRuntimeError, "closure args: %d", type); } @@ -175,6 +179,10 @@ with_gvl_callback(void *ptr) https://github.com/ruby/ruby/blob/trunk/ext/fiddle/closure.c#L179 *(unsigned LONG_LONG *)x->resp = NUM2ULL(ret); break; #endif + case TYPE_CONST_STRING: + /* Dangerous. Callback must keep reference of the String. */ + *((const char **)(x->resp)) = StringValueCStr(ret); + break; default: rb_raise(rb_eRuntimeError, "closure retval: %d", type); } diff --git a/test/fiddle/test_closure.rb b/test/fiddle/test_closure.rb index 6ccd385..9e748bf 100644 --- a/test/fiddle/test_closure.rb +++ b/test/fiddle/test_closure.rb @@ -54,6 +54,19 @@ module Fiddle https://github.com/ruby/ruby/blob/trunk/test/fiddle/test_closure.rb#L54 assert_equal 10, func.call(10) end + def test_const_string + closure_class = Class.new(Closure) do + def call(string) + @return_string = "Hello! #{string}" + @return_string + end + end + closure = closure_class.new(:const_string, [:const_string]) + + func = Function.new(closure, [:const_string], :const_string) + assert_equal("Hello! World!", func.call("World!")) + end + def test_block_caller cb = Closure::BlockCaller.new(TYPE_INT, [TYPE_INT]) do |one| one -- cgit v1.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/