Skip to content

Trouble with struct argument #33

@pekim

Description

@pekim

I was having some problems with a struct argument not being passed to a function correctly. So I created a very simple example, and it still doesn't seem to work.

foo.h

typedef struct
{
  int a;
  unsigned int b;
} something;

void foo(something st);

foo.c

#include <stdio.h>
#include "foo.h"

void foo(something st)
{
  printf("a=%d  b=%d\n", st.a, st.b);
}
# build the shared object
gcc -c -Wall -Werror -fpic foo.c
gcc -shared -o libfoo.so foo.o

main-cgo.go

package main

// #include "foo.h"
//
// #cgo LDFLAGS: -L. -lfoo
import "C"

func main() {
	st := C.something{
		a: 42,
		b: 19,
	}

	C.foo(st)
}
# prove that the shared library works with cgo

LD_LIBRARY_PATH=. go run main-cgo.go
a=42  b=19

main-goffi.go

package main

import (
	"structs"
	"unsafe"

	"github.com/go-webgpu/goffi/ffi"
	"github.com/go-webgpu/goffi/types"
)

var somethingTypeDescriptor = &types.TypeDescriptor{
	Alignment: 8,
	Kind:      types.StructType,
	Members: []*types.TypeDescriptor{
		types.SInt32TypeDescriptor,
		types.UInt32TypeDescriptor,
	},
	Size: 8,
}

func main() {
	var cif_foo = &types.CallInterface{}
	var ptr_foo unsafe.Pointer

	library, err := ffi.LoadLibrary("libfoo.so")
	if err != nil {
		panic(err)
	}

	ptr_foo, err = ffi.GetSymbol(library, "foo")
	if err != nil {
		panic(err)
	}
	returnType := types.VoidTypeDescriptor
	argTypes := []*types.TypeDescriptor{
		somethingTypeDescriptor,
	}
	err = ffi.PrepareCallInterface(cif_foo, types.DefaultCall, returnType, argTypes)
	if err != nil {
		panic(err)
	}

	st := struct {
		_ structs.HostLayout

		a int32
		b uint32
	}{
		a: 42,
		b: 19,
	}

	args := []unsafe.Pointer{
		unsafe.Pointer(&st),
	}

	err = ffi.CallFunction(
		cif_foo,
		ptr_foo,
		nil,
		args,
	)
	if err != nil {
		panic(err)
	}
}
# call the foo function using goffi

CGO_ENABLED=0 LD_LIBRARY_PATH=. go run main-goffi.go
a=1101152704  b=2028

CGO_ENABLED=0 LD_LIBRARY_PATH=. go run main-goffi.go
a=-1580326472  b=11683

It prints apparently random values.

What on earth am I doing wrong? Is goffi not for general use, and only expected to work with webgpu?

Metadata

Metadata

Assignees

No one assigned

    Labels

    abi: system-vSystem V AMD64 ABI (Linux/macOS x86-64)arch: amd64x86-64 specific (System V / Win64 ABI)feature: structsStruct passing/return (HFA, by-value)priority: highImportant for next releasestatus: confirmedVerified, ready for worktype: bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions