Golang вызов функций из общей библиотеки c с использованием cgo - PullRequest
1 голос
/ 06 апреля 2020

Я довольно плохо знаком с более низкоуровневыми языками программирования, поэтому извините, если ответ полностью очевиден.

Для проекта мне нужно импортировать общую библиотеку (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)». Как я могу привести это к вызову функции?

Спасибо за любую помощь.

1 Ответ

1 голос
/ 06 апреля 2020

Вы должны определить указатель на вашу функцию в разделе / ​​* * / import "C". Затем вы можете инициализировать указатель с результатом вызова dlsym. Затем вы можете вызвать вашу функцию как C .your_function (... некоторые аргументы).

Кстати, вы можете попробовать использовать мой пакет 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 (...). Попробуйте взглянуть на тесты для получения дополнительной информации о том, как его можно использовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...