2021-08-17 | 阅读(1,607)
libadd.so
if 条件1 {
loadLibrary("libadd1.so")
调用其中的实现函数 add
else if 条件 2 {
loadLibrary("libadd2.so")
调用其中的实现函数 add
else {
loadLibrary("libaddx.so")
调用其中的实现函数 add
当然上面那样写是不行的,首先每一个动态库应该在程序运行期间只加载一次,定位的函数应该要缓存起来复用。
这时候我们是不能用 #cgo 的方式,像
1 2 3 4 5 6 |
/* #cgo CFLAGS: -I. #cgo LDFLAGS: -L../lib -ladd -Wl,-rpath,lib #include "add.h" */ import "C" |
因为它只能在编译构建期加载 libadd.so
System.loadLibrary("libadd")
1 |
char* Add(char* src, int n); |
libadd.soAdd
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
package main import "C" import ( "fmt" "github.com/rainycape/dl" ) func main() { lib, err := dl.Open("./libadd.so", 0) if err != nil { panic(err) } defer lib.Close() var add func(src *C.char, y int) (*C.char) // 定义函数变量匹配 libadd 中的 Add 函数 lib.Sym("Add", &add) // 定位 Add 函数地址 val := add(C.CString("go"), 2021) fmt.Println("Hello c value: ", C.GoString(val)) } |
go get github.com/rainycape/dl,
$ go run test.go
Hello c value: go2021
成功。
该项目的最后更新日期是 7 年前 (2015),如果稳定倒无妨,或者可以阅读它的实现代码,主要实现是步骤是
1 2 |
C.dlopen(library, flag) C.dlsym(lib_handle, symbol_name) |
go build -buildmode=plugin
链接: