我对更底层的编程语言还很陌生,如果答案很明显,我很抱歉。
对于一个项目,我需要导入一个共享库(sdk.so)并调用它的函数。与 nm -D /lib/sdk.so --defined-only
我可以查看导出的函数,所以我知道它们存在。
现在我想调用某些函数,所以我加载了库:
package main
// #cgo LDFLAGS: -ldl
// #include <stdlib.h>
// #include <dlfcn.h>
import "C"
import (
"errors"
"fmt"
"log"
"unsafe"
)
libName := "sdk"
libName := C.CString(name)
defer C.free(unsafe.Pointer(libName))
handle := C.dlopen(libName, C.RTLD_LAZY)
if handle == nil {
return nil, ErrSoNotFound
}
sym := C.CString("some_function")
defer C.free(unsafe.Pointer(sym))
someFunction := C.dlsym(handle, sym)
if mdpSdkAlloc == nil {
log.Fatal(ErrSoFunctionNotFound)
}
fmt.Println(someFunction)
但是现在我被卡住了,不知道如何调用该函数。 Println 打印出类似 0x7f50a5f9cec0 的内容,带有 & 符号我得到类似 0xc0000b2018 的内容,并且带有星号我得到“someFunction 的无效间接(类型 unsafe.Pointer)”。如何将其转换为函数调用?
谢谢你的帮助。
最佳答案
您必须在/* */import "C"部分中定义指向您的函数的指针。然后您可以使用 dlsym 调用的结果初始化指针。然后你可以调用你的函数,比如 C.your_function(...some arguments)。
对了,你可以尝试使用我的go-dl包来简化它https://github.com/sudachen/go-dl
go-dl 使用可以找到共享库的位置的声明性规范。例如,我们想在系统库中搜索共享库,一些自定义位置,然后如果没有找到下载和/或从缓存加载。
so := dl.Load(
// firstly do search for system libraries
dl.System("libsdk.so"),
// then in the some custom place,
// it can be specified many times for different places
dl.Custom("/opt/sdk/libsdk.so"),
// in download cache
dl.Cached("sdk/sdk.so"),
// if nothing found download to cache and use cache
dl.LzmaExternal(urlbase+"sdk.so.xz"))
但是,您仍然必须定义 C 函数指针以通过 SO.Bind(...) 方法绑定(bind)库符号。尝试查看测试以获取有关如何使用它的更多信息。
关于c - Golang 使用 cgo 从共享 c 库调用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61049887/