github.com/ebitengine/purego

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;
}




type A interface {
Func() uintptr
}

type B struct {
f func() uintptr
}

func (b *B) Func() uintptr {
return b.f()
}

func re(f func() uintptr) A {
return &B{f}
}

func TestNameX(t *testing.T) {
var f func() uintptr
fmt.Println(re(f).Func())
}
 
posted @ 2024-08-03 07:48  zJanly  阅读(93)  评论(0编辑  收藏  举报