2

I'm pretty new to more low level programming languages, so sorry if the answer is totally obvious.

For a project I need to import a shared library (sdk.so) and call its functions. With nm -D /lib/sdk.so --defined-only I can view the exported functions, so I know that they exist.

Now I want to call certain functions, so I load the library:

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)

But now I'm stuck and don't know how to call the function. The Println prints something like 0x7f50a5f9cec0, with an ampersand I'm getting something like 0xc0000b2018 and with an asterisk I'm getting "invalid indirect of someFunction (type unsafe.Pointer)". How can i cast this to a function call?

Thanks for any help.

3
  • 1
    Please see this answer. Commented Apr 5, 2020 at 22:49
  • You can try this very unsafe thingy github.com/LaevusDexter/asmcgocall Commented Apr 6, 2020 at 1:21
  • @Mark i did actually find this post before, but i wouldn't know how to set the LDFLAGS and what .h to include Commented Apr 6, 2020 at 10:30

1 Answer 1

1

You have to define a pointer to your function in /* */import "C" section. Then you can initialize the pointer with the result of dlsym call. Then you can call your function like C.your_function(...some arguments).

By the way, you can try to use my go-dl package to simplify it https://github.com/sudachen/go-dl

The go-dl uses the declarative specification of places where the shared library can be found. For example, we want to search the shared library in system libraries, some custom place and then if nothing found download and/or load from cache.

   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"))  

However, you still have to define the C function pointer to bind library symbols by SO.Bind(...) method. Try to look at tests for more information about how it can be used.

Sign up to request clarification or add additional context in comments.

3 Comments

and how do I use your library? If I do dl.Load("sdk.so") I get not found or failed to load dynamic library
I added an explanation to my answer.
Thank you very much, I think I got it.. at least I'm getting something back and no errors anymore!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.