Calling functions in an so file from Go

前端 未结 3 1049
再見小時候
再見小時候 2020-12-31 14:30

Is it possible to call a static object (.so) file from Go? I\'ve been searchign Google and I keep hitting upon the claim that I can do

lib, _ := syscall.Load         


        
相关标签:
3条回答
  • 2020-12-31 15:04

    On a POSIX platform, you could use cgo to call dlopen and friends:

    // #cgo LDFLAGS: -ldl
    // #include <dlfcn.h>
    import "C"
    
    import fmt
    
    func foo() {
         handle := C.dlopen(C.CString("libfoo.so"), C.RTLD_LAZY)
         bar := C.dlsym(handle, C.CString("bar"))
         fmt.Printf("bar is at %p\n", bar)
    }
    
    0 讨论(0)
  • 2020-12-31 15:05

    As @JimB said, you should just use CGO, and put the linking to the dynamic/static library there. as per this example:

    // #cgo LDFLAGS: -lpng
    // #include <png.h>
    import "C"
    
    ...
    
    var x:= C.png_whatever() // whatever the API is
    

    Read more here: http://blog.golang.org/c-go-cgo

    0 讨论(0)
  • 2020-12-31 15:14

    The answer by @Martin Törnwall explains how to use dlopen() for function lookup. Adding this answer to include sample code for how to actually call that function as well. (Using the approach suggested in the comments).

    The idea is to write a wrapper function in C language for each function the shared library, which accepts a void* pointer (pointer to the function returned by dlopen()), converts it into an appropriate function pointer, and then call it.

    Suppose we have a function named str_length in libfoo.so to calculate the length of a string, then the resulting Go code would be:

    package main
    
    import (
        "fmt"
    )
    
    /*
    #cgo LDFLAGS: -ldl
    #include <dlfcn.h>
    
    typedef int (*str_length_type)(char*); // function pointer type
    
    int str_length(void* f, char* s) { // wrapper function
        return ((str_length_type) f)(s);
    }
    */
    import "C"
    
    func main() {
        handle := C.dlopen(C.CString("libfoo.so"), C.RTLD_LAZY)
        str_length_ptr := C.dlsym(handle, C.CString("str_length"))
        result := C.str_length(str_length_ptr, C.CString("Hello World!"))
        fmt.Println(result) // prints 12
    }
    
    0 讨论(0)
提交回复
热议问题