package ffi import ( "unsafe" c "github.com/goplus/llgo/runtime/internal/clite" "github.com/goplus/llgo/runtime/internal/clite/ffi" ) type Type = ffi.Type type Signature = ffi.Cif type Error int func (s Error) Error() string { switch s { case ffi.OK: return "ok" case ffi.BAD_TYPEDEF: return "bad type def" case ffi.BAD_ABI: return "bad ABI" case ffi.BAD_ARGTYPE: return "bad argument type" } return "invalid status" } func NewSignature(ret *Type, args ...*Type) (*Signature, error) { var cif Signature var atype **Type if len(args) > 0 { atype = &args[0] } status := ffi.PrepCif(&cif, ffi.DefaultAbi, c.Uint(len(args)), ret, atype) if status == 0 { return &cif, nil } return nil, Error(status) } func NewSignatureVar(ret *Type, fixed int, args ...*Type) (*Signature, error) { var cif Signature var atype **Type if len(args) > 0 { atype = &args[0] } status := ffi.PrepCifVar(&cif, ffi.DefaultAbi, c.Uint(fixed), c.Uint(len(args)), ret, atype) if status == ffi.OK { return &cif, nil } return nil, Error(status) } func Call(cif *Signature, fn unsafe.Pointer, ret unsafe.Pointer, args ...unsafe.Pointer) { var avalues *unsafe.Pointer if len(args) > 0 { avalues = &args[0] } ffi.Call(cif, fn, ret, avalues) } type Closure struct { ptr unsafe.Pointer Fn unsafe.Pointer } func NewClosure() *Closure { c := &Closure{} c.ptr = ffi.ClosureAlloc(&c.Fn) return c } func (c *Closure) Free() { if c != nil && c.ptr != nil { ffi.ClosureFree(c.ptr) c.ptr = nil } } func (c *Closure) Bind(cif *Signature, fn ffi.ClosureFunc, userdata unsafe.Pointer) error { status := ffi.PreClosureLoc(c.ptr, cif, fn, userdata, c.Fn) if status == ffi.OK { return nil } return Error(status) } func Index(args *unsafe.Pointer, i uintptr) unsafe.Pointer { return ffi.Index(args, i) }