github.com/ebitengine/purego

zJanly發表於2024-08-03

https://blog.webp.se/golang-libvips-cgo-zh/

package main

import (
	"fmt"
	"github.com/ebitengine/purego"
	"runtime"
)

func getSystemLibrary() string {
	switch runtime.GOOS {
	case "darwin":
		return "/usr/lib/libSystem.B.dylib"
	case "linux":
		return "libc.so.6"
	default:
		panic(fmt.Errorf("GOOS=%s is not supported", runtime.GOOS))
	}
}

func getCustomLibrary() string {
	switch runtime.GOOS {
	case "darwin":
		return "calc.dylib"
	case "linux":
		return "./calc.so" // 注意這裡的 ./,否則就要 symbolic link 到 /lib
	default:
		panic(fmt.Errorf("GOOS=%s is not supported", runtime.GOOS))
	}
}

func main() {
	libc, err := purego.Dlopen(getSystemLibrary(), purego.RTLD_NOW|purego.RTLD_GLOBAL)
	if err != nil {
		panic(err)
	}

	var timeFunc func() int64
	purego.RegisterLibFunc(&timeFunc, libc, "time")
	x := timeFunc()
	fmt.Println("timeFunc from purego: ", x)

	calc, err := purego.Dlopen(getCustomLibrary(), purego.RTLD_NOW|purego.RTLD_GLOBAL)
	if err != nil {
		panic(err)
	}
	var volumeFunc func(float64) float64
	purego.RegisterLibFunc(&volumeFunc, calc, "volume")
	res := volumeFunc(5.3)

	fmt.Println("volumeFunc: ", res)

}



CGO_ENABLED=0 go build



#include <stdio.h>
#include <math.h>

double volume(double radius)
{
    double volume = (4.0f / 3.0f) * M_PI * pow(radius, 3);
    printf("radius: %f, volume: %f\\n", radius, volume);
    return volume;
}


相關文章