基于ebitengine/purego的easytier-ffi golang 包
以前简单基于cgo 处理过easytier-ffi 的集成,以下是通过ebitengine/purego 实现一个基于purego 的集成
方法定义
实际核心是通过ebitengine/purego 进行方法注册,代码上就是标准的purego玩法
package easytier
import (
"os"
"os/exec"
"github.com/ebitengine/purego"
)
type KeyValuePair struct {
Key *byte
Value *byte
}
var (
GetErrorMsg func(*byte)
FreeString func(*byte)
ParseConfig func(*byte) int32
RunNetworkInstance func(*byte) int32
RetainNetworkInstance func(*byte, uintptr) int32
CollectNetworkInfos func(*KeyValuePair, uintptr) int32
)
func findLibrary() string {
// Env var
if envPath := os.Getenv("EASYTIER_FFI_LIB_PATH"); envPath != "" {
return envPath
}
// ldconfig with Linux
if path, err := exec.LookPath("libeasytier_ffi.so"); err == nil {
return path
}
// default path
commonPaths := []string{
"/usr/local/lib/libeasytier_ffi.so",
"./lib/libeasytier_ffi.dylib",
"./lib/libeasytier_ffi.so",
"./lib/libeasytier_ffi.dll",
"/usr/lib/libeasytier_ffi.so",
"/opt/homebrew/lib/libeasytier_ffi.dylib",
}
for _, p := range commonPaths {
if _, err := os.Stat(p); err == nil {
return p
}
}
return "libeasytier_ffi.so"
}
func init() {
path := findLibrary()
libeasytier, err := purego.Dlopen(path, purego.RTLD_NOW|purego.RTLD_GLOBAL)
if err != nil {
panic(err)
}
purego.RegisterLibFunc(&GetErrorMsg, libeasytier, "get_error_msg")
purego.RegisterLibFunc(&FreeString, libeasytier, "free_string")
purego.RegisterLibFunc(&ParseConfig, libeasytier, "parse_config")
purego.RegisterLibFunc(&RunNetworkInstance, libeasytier, "run_network_instance")
purego.RegisterLibFunc(&RetainNetworkInstance, libeasytier, "retain_network_instance")
purego.RegisterLibFunc(&CollectNetworkInfos, libeasytier, "collect_network_infos")
}
应用使用
为了方便基于配置,然后调用ffi 的方法
- main.go
package main
import (
"fmt"
"os"
"time"
easytierffigo "github.com/rongfengliang/easytier-ffi-go/easytier"
)
func main() {
data, err := os.ReadFile("app.yaml")
if err != nil {
panic(err)
}
content := string(data)
// 使用工具类,讲string 转为*byte
_, cstr := easytierffigo.CString(content)
result := easytierffigo.ParseConfig(cstr)
fmt.Println("ParseConfig result", result)
if result != 0 {
fmt.Println("Error parsing config:")
}
result = easytierffigo.RunNetworkInstance(cstr)
if result != 0 {
fmt.Println("Error running network instance")
} else {
fmt.Println("Network instance started successfully")
}
for {
fmt.Println("looping...")
time.Sleep(1 * time.Second)
}
}
说明
基于ebitengine/purego的好处是我们的代码是纯go的,跨平台会好一些,但是实际问题也是有的,比如性能可能不如cgo 好,但是对于easytier 来时没啥影响,相关代码我已经push github 了,可以直接使用
参考资料
https://github.com/rongfengliang/easytier-ffi-go
https://github.com/chdb-io/chdb-go
https://github.com/ebitengine/purego
https://github.com/rongfengliang/easytier-ffi-cgo
https://github.com/ebitengine/purego
https://easytier.cn/web/index.html#/config_generator
https://github.com/EasyTier/EasyTier/tree/main/easytier-contrib/easytier-ffi
浙公网安备 33010602011771号