Calling functions in an so file from Go
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)
}
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
}
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