diff --git a/ext/ffi_c/Function.c b/ext/ffi_c/Function.c index 177180003..1bf751c27 100644 --- a/ext/ffi_c/Function.c +++ b/ext/ffi_c/Function.c @@ -721,7 +721,7 @@ invoke_callback(VALUE data) param = rb_float_new(*(double *) parameters[i]); break; case NATIVE_LONGDOUBLE: - param = rbffi_longdouble_new(*(long double *) parameters[i]); + param = rbffi_longdouble_new(*(long double *) parameters[i]); break; case NATIVE_STRING: param = (*(void **) parameters[i] != NULL) ? rb_str_new2(*(char **) parameters[i]) : Qnil; @@ -793,6 +793,9 @@ invoke_callback(VALUE data) case NATIVE_FLOAT64: *((double *) retval) = NUM2DBL(rbReturnValue); break; + case NATIVE_LONGDOUBLE: + *((long double *) retval) = rbffi_num2longdouble(rbReturnValue); + break; case NATIVE_POINTER: if (TYPE(rbReturnValue) == T_DATA && rb_obj_is_kind_of(rbReturnValue, rbffi_PointerClass)) { *((void **) retval) = ((AbstractMemory *) DATA_PTR(rbReturnValue))->address; diff --git a/spec/ffi/fixtures/ClosureTest.c b/spec/ffi/fixtures/ClosureTest.c index 1e7574873..c477be8a7 100644 --- a/spec/ffi/fixtures/ClosureTest.c +++ b/spec/ffi/fixtures/ClosureTest.c @@ -35,6 +35,7 @@ R(J, long long); R(LL, long long); R(F, float); R(D, double); +R(LD, long double); R(P, const void*); @@ -47,6 +48,7 @@ P(J, long long); P(LL, long long); P(F, float); P(D, double); +P(LD, long double); P(P, const void*); P(UL, unsigned long); diff --git a/spec/ffi/long_double_spec.rb b/spec/ffi/long_double_spec.rb index 86f60c377..3128d9686 100644 --- a/spec/ffi/long_double_spec.rb +++ b/spec/ffi/long_double_spec.rb @@ -7,10 +7,17 @@ require 'bigdecimal' # long double not yet supported on TruffleRuby -describe ":long_double arguments and return values", if: RUBY_PLATFORM !~ /mingw|mswin/ do +describe ":long_double arguments and return values" do module LibTest extend FFI::Library ffi_lib TestLibrary::PATH + + callback :cbVrLD, [ ], :long_double + attach_function :testCallbackVrLD, :testClosureVrLD, [ :cbVrLD ], :long_double + + callback :cbLDrV, [ :long_double ], :void + attach_function :testCallbackLDrV, :testClosureLDrV, [ :cbLDrV, :long_double ], :void + attach_function :add_f128, [ :long_double, :long_double ], :long_double attach_function :ret_f128, [ :long_double ], :long_double end @@ -28,4 +35,16 @@ module LibTest it "add two long double numbers" do expect(LibTest.add_f128(0.1, 0.2)).to be_within(0.01).of(0.3) end + + describe "Callback" do + it "returning :long_double" do + expect(LibTest.testCallbackVrLD { -0.1 }).to be_within(0.01).of(-0.1) + end + + it ":long_double argument" do + v = nil + LibTest.testCallbackLDrV(0.1) { |i| v = i } + expect(v).to be_within(0.01).of(0.1) + end + end end if RUBY_ENGINE != "truffleruby"