Go bindings to libffi
go-ffi is interesting when a program needs to call C functions in a way that is not yet supported by cgo. For example if the function pointer was obtained dynamically or if the function as a variadic signature.
Here's an example showing how to call printf from Go using the go-ffi package:
package main
// #include <stdio.h>
//
// const void *printf__ = (void *) printf;
import "C"
import "github.com/achille-roussel/go-ffi"
func main() {
ffi.Call(C.printf__, nil, "%s %s!\n", "Hello", "World")
}
Hello World!
go-ffi also provides a mechanism for generating pointers that can be used to
call Go functions from compiled C code.
Here's an example showing how this is done:
package main
import (
"fmt"
"strconv"
"unsafe"
"github.com/achille-roussel/go-ffi"
)
func main() {
itoa := ffi.Closure(strconv.Itoa)
fptr := itoa.Pointer()
repr := ""
ffi.Call(unsafe.Pointer(fptr), &repr, 42)
fmt.Println(repr)
}
42
go-ffi automatically converts between C and Go types when using the high-level
interfaces.
The following table exposes what conversions are supported:
Go | C |
---|---|
int | int |
int8 | int8_t |
int16 | int16_t |
int32 | int32_t |
int64 | int64_t |
uint | unsigned int |
uint8 | uint8_t |
uint16 | uint16_t |
uint32 | uint32_t |
uintptr | size_t |
float32 | float |
float64 | double |
string | char * |
unsafe.Pointer | void * |