【发布时间】:2026-02-24 13:20:05
【问题描述】:
您好,我将在 linux 环境中使用 golang 使用第三方库(.so 文件)。所以我试着用一些琐碎的东西来练习一下,比如从 linux 原生库中导入函数。并被困在导入和调用 sqrt 函数上。这是我的代码:
package main
// #cgo LDFLAGS: -ldl
// #include <dlfcn.h>
// #include <stdio.h>
import "C"
import "fmt"
func main() {
export_name := "sqrt"
lib_path := "/lib/libm.so.6"
//Loading .so
handle := C.dlopen(C.CString(lib_path), C.RTLD_LAZY)
if handle == nil {
fmt.Println(lib_path+":\tNOT FOUND")
return
} else {
fmt.Println(lib_path+":\tSUCCESS")
}
//looking for function address
func_pointer := C.dlsym(handle, C.CString(export_name ))
if func_pointer == nil {
fmt.Println(export_name+":\tNOT FOUND")
return
} else {
fmt.Println(export_name+":\t", func_pointer)
}
//negotiating datatypes
//From c lib description: double sqrt(double x);
sqrt := *(*(func(float64)float64))(func_pointer)
//Calling function
sqrt(4)
}
当我运行它时,我总是遇到分段违规:
/lib/libm.so.6: SUCCESS
sqrt: 0x7f37117ea270
unexpected fault address 0x0
fatal error: fault
[signal SIGSEGV: segmentation violation code=0x80 addr=0x0 pc=0x4019fa]
goroutine 1 [running]:
runtime.throw(0x4a6643, 0x5)
/usr/lib/go/src/runtime/panic.go:566 +0x95 fp=0xc42004be00 sp=0xc42004bde0
runtime.sigpanic()
/usr/lib/go/src/runtime/sigpanic_unix.go:27 +0x288 fp=0xc42004be58 sp=0xc42004be00
main.main()
/home/afx/goc/so.go:37 +0x2ba fp=0xc42004bf48 sp=0xc42004be58
runtime.main()
/usr/lib/go/src/runtime/proc.go:183 +0x1f4 fp=0xc42004bfa0 sp=0xc42004bf48
runtime.goexit()
/usr/lib/go/src/runtime/asm_amd64.s:2086 +0x1 fp=0xc42004bfa8 sp=0xc42004bfa0
goroutine 17 [syscall, locked to thread]:
runtime.goexit()
/usr/lib/go/src/runtime/asm_amd64.s:2086 +0x1
exit status 2
有什么问题? 提前谢谢你。
附: 当我重新定义本机 Go 函数的函数指针时(比如这里 Go: convert unsafe.Pointer to function pointer and vice versa),一切正常。但是导入失败。
【问题讨论】:
-
我认为你不能那样做。看这个例子,可以用静态桥接函数github.com/coreos/pkg/blob/master/dlopen/dlopen_example.go
-
谢谢!桥接功能是缺失的环节。
标签: c linux go shared-libraries