Skip to content

Commit

Permalink
purego: fix float returns (#177)
Browse files Browse the repository at this point in the history
The bits for a float32 return value were being converted into a float64. This causes the returned value to be incorrect. This fix was to separate the float32 case and use math.Float32frombits. The test just makes sure that float32 and float64 return values are returned from C functions correctly.
  • Loading branch information
TotallyGamerJet authored Nov 18, 2023
1 parent cb05b2a commit 63c6fec
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 5 deletions.
6 changes: 5 additions & 1 deletion func.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,11 @@ func RegisterFunc(fptr interface{}, cfn uintptr) {
RegisterFunc(v.Interface(), r1)
case reflect.String:
v.SetString(strings.GoString(r1))
case reflect.Float32, reflect.Float64:
case reflect.Float32:
// NOTE: r2 is only the floating return value on 64bit platforms.
// On 32bit platforms r2 is the upper part of a 64bit return.
v.SetFloat(float64(math.Float32frombits(uint32(r2))))
case reflect.Float64:
// NOTE: r2 is only the floating return value on 64bit platforms.
// On 32bit platforms r2 is the upper part of a 64bit return.
v.SetFloat(math.Float64frombits(uint64(r2)))
Expand Down
43 changes: 39 additions & 4 deletions func_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ func getSystemLibrary() (string, error) {
func TestRegisterFunc(t *testing.T) {
library, err := getSystemLibrary()
if err != nil {
t.Errorf("couldn't get system library: %s", err)
t.Fatalf("couldn't get system library: %s", err)
}
libc, err := openLibrary(library)
if err != nil {
t.Errorf("failed to dlopen: %s", err)
t.Fatalf("failed to dlopen: %s", err)
}
var puts func(string)
purego.RegisterLibFunc(&puts, libc, "puts")
Expand All @@ -65,11 +65,11 @@ func ExampleNewCallback() {
func Test_qsort(t *testing.T) {
library, err := getSystemLibrary()
if err != nil {
t.Errorf("couldn't get system library: %s", err)
t.Fatalf("couldn't get system library: %s", err)
}
libc, err := openLibrary(library)
if err != nil {
t.Errorf("failed to dlopen: %s", err)
t.Fatalf("failed to dlopen: %s", err)
}

data := []int{88, 56, 100, 2, 25}
Expand All @@ -86,3 +86,38 @@ func Test_qsort(t *testing.T) {
}
}
}

func TestRegisterFunc_Floats(t *testing.T) {
library, err := getSystemLibrary()
if err != nil {
t.Fatalf("couldn't get system library: %s", err)
}
libc, err := openLibrary(library)
if err != nil {
t.Fatalf("failed to dlopen: %s", err)
}
{
var strtof func(arg string) float32
purego.RegisterLibFunc(&strtof, libc, "strtof")
const (
arg = "2"
)
got := strtof(arg)
expected := float32(2)
if got != expected {
t.Errorf("strtof failed. got %f but wanted %f", got, expected)
}
}
{
var strtod func(arg string, ptr **byte) float64
purego.RegisterLibFunc(&strtod, libc, "strtod")
const (
arg = "1"
)
got := strtod(arg, nil)
expected := float64(1)
if got != expected {
t.Errorf("strtod failed. got %f but wanted %f", got, expected)
}
}
}

0 comments on commit 63c6fec

Please sign in to comment.