Documentation ¶
Index ¶
Constants ¶
const ( Void = iota Int Float Double Longdouble Uint8 Sint8 Uint16 Sint16 Uint32 Sint32 Uint64 Sint64 Struct Pointer Complex )
These constants are used for the Type field of Type.
Variables ¶
var ( TypeVoid = Type{1, 1, Void, nil} TypeUint8 = Type{1, 1, Uint8, nil} TypeSint8 = Type{1, 1, Sint8, nil} TypeUint16 = Type{2, 2, Uint16, nil} TypeSint16 = Type{2, 2, Sint16, nil} TypeUint32 = Type{4, 4, Uint32, nil} TypeSint32 = Type{4, 4, Sint32, nil} TypeUint64 = Type{8, 8, Uint64, nil} TypeSint64 = Type{8, 8, Sint64, nil} TypeFloat = Type{4, 4, Float, nil} TypeDouble = Type{8, 8, Double, nil} TypePointer = Type{8, 8, Pointer, nil} TypeLongdouble = Type{16, 16, Longdouble, nil} TypeComplexFloat = Type{8, 4, Complex, &[]*Type{&TypeFloat, nil}[0]} TypeComplexDouble = Type{16, 8, Complex, &[]*Type{&TypeDouble, nil}[0]} TypeComplexLongdouble = Type{32, 16, Complex, &[]*Type{&TypeLongdouble, nil}[0]} )
Predefined variables for primitive data types.
For bool you can use TypeUint32 and check its value (0 = false, 1 = true).
A string is just an array of characters in C (often seen as char * or const char *). Use TypePointer for that.
To convert strings between C and Go take a look at golang.org/x/sys/unix.BytePtrFromString and golang.org/x/sys/unix.BytePtrToString.
Slices are treated as pointers as well. You can use unsafe.Slice to convert a pointer into a slice.
Functions ¶
func Call ¶
Call calls the function fn according to the description given in cif. cif must have already been prepared using PrepCif.
- fn is the address of the desired function. Use purego.Dlsym to get one.
- rValue is a pointer to a variable that will hold the result of the function call. Provide nil if the function has no return value.
- aValues are pointers to the argument values. Leave empty or provide nil if the function takes none.
Example:
double cos(double x); cosine, x := 0.0, 1.0 ffi.Call(&cif, cos, unsafe.Pointer(&cosine), unsafe.Pointer(&x))
Types ¶
type Cif ¶
Cif stands for "Call InterFace". It describes the signature of a function.
Use PrepCif to initialize it.
type Status ¶
type Status uint32
func PrepCif ¶
PrepCif initializes cif.
- abi is the ABI to use. Normally DefaultAbi is what you want.
- nArgs is the number of arguments. Use 0 if the function has none.
- rType is the return type. Use TypeVoid if the function has none.
- aTypes are the arguments. Leave empty or provide nil if the function has none.
The returned status code will be OK, if everything worked properly.
Example:
double cos(double x); var cif ffi.Cif status := ffi.PrepCif(&cif, ffi.DefaultAbi, 1, &ffi.TypeDouble, &ffi.TypeDouble) if status != ffi.OK { panic(status) }
func PrepCifVar ¶
func PrepCifVar(cif *Cif, abi Abi, nFixedArgs, nTotalArgs uint32, rType *Type, aTypes ...*Type) Status
PrepCifVar initializes cif for a call to a variadic function.
In general its operation is the same as for PrepCif except that:
- nFixedArgs is the number of fixed arguments, prior to any variadic arguments. It must be greater than zero.
- nTotalArgs is the total number of arguments, including variadic and fixed arguments. aTypes must have this many elements.
This function will return BadArgType if any of the variable argument types is TypeFloat. Same goes for integer types smaller than 4 bytes. See issue 608.
Note that, different cif's must be prepped for calls to the same function when different numbers of arguments are passed.
Also note that a call to this function with nFixedArgs = nTotalArgs is NOT equivalent to a call to PrepCif.
Example:
int printf(const char *restrict format, ...); var cif ffi.Cif status := ffi.PrepCifVar(&cif, ffi.DefaultAbi, 1, 2, &ffi.TypeSint32, &ffi.TypePointer, &ffi.TypeDouble) if status != ffi.OK { panic(status) } text, _ := unix.BytePtrFromString("Pi is %f\n") pi := math.Pi var nCharsPrinted int32 ffi.Call(&cif, printf, unsafe.Pointer(&nCharsPrinted), unsafe.Pointer(&text), unsafe.Pointer(&pi))
type Type ¶
type Type struct { Size uint64 // Initialize to 0 (automatically set by libffi as needed). Alignment uint16 // Initialize to 0 (automatically set by libffi as needed). Type uint16 // Use ffi.Struct for struct types. Elements **Type // Pointer to the first element of a nil-terminated slice. }
Type is used to describe the structure of a data type.
Example:
typedef struct Point { int x; int y; } Point; typePoint := ffi.Type{Type: ffi.Struct, Elements: &[]*ffi.Type{&ffi.TypeSint32, &ffi.TypeSint32, nil}[0]}
Primitive data types are already defined (e.g. TypeDouble for float64).