ffi

package module
v0.1.0-beta.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 4, 2024 License: MIT Imports: 4 Imported by: 3

README

ffi

Go Reference

A libffi wrapper for purego.

Purpose

You can use purego to call C code without cgo. ffi provides extra functionality (e.g. passing and returning structs by value).

Requirements

OS

Any 64-bit Linux distribution should work.

Software

libffi is preinstalled on most distributions, because it also is a dependency of Python and Ruby. If not, you can install it explicitly:

Debian 12, Ubuntu 22.04, Ubuntu 24.04
sudo apt install libffi8
Arch Linux
sudo pacman -S libffi

Examples

In this example we use the puts function inside the standard C library to print "Hello World!" to the console:

extern int puts (const char *__s);
package main

import (
	"unsafe"

	"github.com/ebitengine/purego"
	"github.com/jupiterrider/ffi"
	"golang.org/x/sys/unix"
)

func main() {
	// open the C library
	libm, err := purego.Dlopen("libc.so.6", purego.RTLD_LAZY)
	if err != nil {
		panic(err)
	}

	// get the address of puts
	puts, err := purego.Dlsym(libm, "puts")
	if err != nil {
		panic(err)
	}

	// describe the function's signature
	var cif ffi.Cif
	if ok := ffi.PrepCif(&cif, ffi.DefaultAbi, 1, &ffi.TypeSint32, &ffi.TypePointer); ok != ffi.OK {
		panic("ffi prep failed")
	}

	// convert the go string into a pointer
	text, _ := unix.BytePtrFromString("Hello World!")

	// call the puts function
	ffi.Call(&cif, puts, nil, unsafe.Pointer(&text))
}

You can find more examples inside the examples folder of this repository.

Documentation

Index

Constants

View Source
const (
	Void = iota
	Int
	Float
	Double
	Longdouble
	Uint8
	Sint8
	Uint16
	Sint16
	Uint32
	Sint32
	Uint64
	Sint64
	Struct
	Pointer
	Complex
)

Variables

View Source
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]}
)

Functions

func Call

func Call(cif *Cif, fn uintptr, rValue unsafe.Pointer, aValues ...unsafe.Pointer)

Types

type Abi

type Abi uint32
const (
	DefaultAbi Abi = 2
)

type Cif

type Cif struct {
	Abi      uint32
	NArgs    uint32
	ArgTypes **Type
	RType    *Type
	Bytes    uint32
	Flags    uint32
}

type Status

type Status uint32
const (
	OK Status = iota
	BadTypedef
	BadAbi
	BadArgType
)

func PrepCif

func PrepCif(cif *Cif, abi Abi, nArgs uint32, rType *Type, aTypes ...*Type) Status

type Type

type Type struct {
	Size      uint64
	Alignment uint16
	Type      uint16
	Elements  **Type
}

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL