Call a function in a shared library: Difference between revisions
Content added Content deleted
(Removed {{omit from/Go}}) |
(Added Go) |
||
Line 811: | Line 811: | ||
Print "Press any key to quit" |
Print "Press any key to quit" |
||
Sleep</lang> |
Sleep</lang> |
||
=={{header|Go}}== |
|||
{{trans|C}} |
|||
{{works with|Ubuntu 18.04}} |
|||
<br> |
|||
Dynamically calling a function from a shared library can only be accomplished in Go using 'cgo' and, even then, the function pointer returned by 'dlsysm' can only be called via a C bridging function as calling C function pointers directly from Go is not currently supported. |
|||
This is the C code to produce fakeimglib.so: |
|||
<lang c>#include <stdio.h> |
|||
/* gcc -shared -fPIC -nostartfiles fakeimglib.c -o fakeimglib.so */ |
|||
int openimage(const char *s) |
|||
{ |
|||
static int handle = 100; |
|||
fprintf(stderr, "opening %s\n", s); |
|||
return handle++; |
|||
}</lang> |
|||
And this is the Go code to dynamically load the .so file and call the 'openimage' function - or if the .so file (or the function itself) is not available, to call the internal version of the function: |
|||
<lang go>package main |
|||
/* |
|||
#cgo LDFLAGS: -ldl |
|||
#include <stdlib.h> |
|||
#include <dlfcn.h> |
|||
typedef int (*someFunc) (const char *s); |
|||
int bridge_someFunc(someFunc f, const char *s) { |
|||
return f(s); |
|||
} |
|||
*/ |
|||
import "C" |
|||
import ( |
|||
"fmt" |
|||
"os" |
|||
"unsafe" |
|||
) |
|||
var handle = -1 |
|||
func myOpenImage(s string) int { |
|||
fmt.Fprintf(os.Stderr, "internal openImage opens %s...\n", s) |
|||
handle++ |
|||
return handle |
|||
} |
|||
func main() { |
|||
libpath := C.CString("./fakeimglib.so") |
|||
defer C.free(unsafe.Pointer(libpath)) |
|||
imglib := C.dlopen(libpath, C.RTLD_LAZY) |
|||
var imghandle int |
|||
if imglib != nil { |
|||
openimage := C.CString("openimage") |
|||
defer C.free(unsafe.Pointer(openimage)) |
|||
fp := C.dlsym(imglib, openimage) |
|||
if fp != nil { |
|||
fi := C.CString("fake.img") |
|||
defer C.free(unsafe.Pointer(fi)) |
|||
imghandle = int(C.bridge_someFunc(C.someFunc(fp), fi)) |
|||
} else { |
|||
imghandle = myOpenImage("fake.img") |
|||
} |
|||
C.dlclose(imglib) |
|||
} else { |
|||
imghandle = myOpenImage("fake.img") |
|||
} |
|||
fmt.Printf("opened with handle %d\n", imghandle) |
|||
}</lang> |
|||
{{output}} |
|||
<pre> |
|||
Same as C entry. |
|||
</pre> |
|||
=={{header|Haskell}}== |
=={{header|Haskell}}== |