diff --git a/Changes b/Changes index 04b92a4d..374b7afc 100644 --- a/Changes +++ b/Changes @@ -1,6 +1,8 @@ Revision history for {{$dist->name}} {{$NEXT}} + - float gets promoted to double when used as a varadic argument + (gh#323, gh#338) 1.48_01 2021-06-22 00:32:02 -0600 - Test forks in CI (gh#333, #334, #335) diff --git a/lib/FFI/Platypus.pm b/lib/FFI/Platypus.pm index 1e920693..959736b4 100644 --- a/lib/FFI/Platypus.pm +++ b/lib/FFI/Platypus.pm @@ -763,10 +763,18 @@ sub function $fixed_args = []; } - my $args = [@$fixed_args, @{ $var_args || [] } ]; my $fixed_arg_count = defined $var_args ? scalar(@$fixed_args) : -1; - my @args = map { $self->{tp}->parse($_) || croak "unknown type: $_" } @$args; + my @args = map { $self->{tp}->parse($_) || croak "unknown type: $_" } @$fixed_args; + if($var_args) + { + push @args, map { + my $type = $self->{tp}->parse($_); + # https://github.com/PerlFFI/FFI-Platypus/issues/323 + $type->type_code == 67 ? $self->{tp}->parse('double') : $type + } @$var_args; + } + $ret = $self->{tp}->parse($ret) || croak "unknown type: $ret"; my $address = $name =~ /^-?[0-9]+$/ ? $name : $self->find_symbol($name); croak "unable to find $name" unless defined $address || $self->ignore_not_found; diff --git a/t/gh323.t b/t/gh323.t new file mode 100644 index 00000000..b541bf56 --- /dev/null +++ b/t/gh323.t @@ -0,0 +1,38 @@ +use Test2::V0 -no_srand => 1; +use FFI::Platypus; +use FFI::Platypus::Memory qw( malloc free ); + +foreach my $api (0,1,2) +{ + + subtest "api => $api" => sub { + + our $ffi = FFI::Platypus->new( api => $api, lib => [undef], experimental => ($api >=2 ? $api : undef)); + + $ffi->type('float' => 'my_float'); + + sub callit + { + my($type) = @_; + + my $ptr = malloc 1024; + $ffi->function( sprintf => ['opaque','string'] => [$type] )->call($ptr, "%f", 3.14); + my $string = $ffi->cast('opaque' => 'string', $ptr); + free $ptr; + return $string; + } + + my $double = callit('double'); + my $float = callit('float'); + note "double = $double"; + note "float = $float"; + is $float, $double; + + $float = callit('my_float'); + note "my_float = $float"; + is $float, $double; + + }; +} + +done_testing;