c - Golang 使用 cgo 从共享 c 库调用函数
问题描述
我对更底层的编程语言还很陌生,如果答案很明显,我很抱歉。
对于一个项目,我需要导入一个共享库(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(...) 方法绑定库符号。尝试查看测试以获取有关如何使用它的更多信息。
推荐阅读
- r - 如何在R中制作一个快速的成对Tanimoto距离函数
- audio - 不同语言的 PESQ、STOI 分数(语音质量)(非英语)
- google-app-engine - 发布请求时出现 Google App Engine 500 内部服务器错误
- node.js - Docker compose 在路径中找不到 package.json
- r - 手动创建从 fromJSON 函数返回的相同数据帧
- javascript - 有不同
当您单击每个单独的部分时,标记值会显示在单独的 div 中
- python - 如何使用 Python 在 1 次写入 DynamoDB 中插入对象列表?
- javascript - 与正常调用函数相比,为什么使用箭头函数会在 React 中提供更新版本的状态?
- c# - 如何用画笔图案填充画布上的矩形?
- javascript - 如何在数组中选择值