c - Golang 使用 cgo 从共享 c 库调用函数

标签 c go cgo .so

我对更底层的编程语言还很陌生,如果答案很明显,我很抱歉。

对于一个项目,我需要导入一个共享库(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/

相关文章:

macos - 为较旧的 Mac OS 版本构建 golang 应用程序的正确方法是什么?

c - 为什么在这种情况下 char 的输出不同?

go - 无法导入 gorilla/mux(github.com/gorilla/mux@v1.7.4 : is explicitly required in go. mod,但在 vendor/modules.txt 中未标记为显式)

pointers - 在Go中返回时C struct为零

sql - 如何使用 GORM 从多对多关系相关的其他表中过滤包含实体的表?

Go嵌套模板路径作为变量

ssl - Golang LD_PRELOAD Hook SSL_read 和 SSL_write

c++ - 试图读取或写入 protected 内存 : C++ Modified Value of Memory

c - 声明和定义相互引用的初始化常量结构的最佳方法

将性能从 size_t 提高一倍