可以从Go语言中调用静态对象(.so)文件吗?我一直在Google上搜索,我一直在寻找我可以做的声明
lib, _ := syscall.LoadLibrary("...")
但尝试这样做会产生错误
undefined: syscall.LoadLibrary
我在Godocs中找不到这个函数的引用。可以加载一个库并调用它的函数吗?
wkyowqbh1#
在POSIX平台上,可以使用cgo调用dlopen和朋友:
cgo
// #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) }
9lowa7mx2#
正如@JimB所说,你应该使用CGO,并将链接放在动态/静态库中。按照这个例子:
// #cgo LDFLAGS: -lpng // #include <png.h> import "C" ... var x:= C.png_whatever() // whatever the API is
在此阅读更多信息:http://blog.golang.org/c-go-cgo
qkf9rpyu3#
@Martin Törnwall的答案解释了如何使用dlopen()进行函数查找。添加此答案以包括如何实际调用该函数的示例代码。(使用注解中建议的方法)。这个想法是用C语言为共享库中的每个函数编写一个 Package 器函数,它接受一个void* 指针(指向dlopen()返回的函数的指针),将其转换为适当的函数指针,然后调用它。假设我们在libfoo.so中有一个名为str_length的函数来计算字符串的长度,那么得到的Go代码将是:
dlopen()
libfoo.so
str_length
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 }
fv2wmkja4#
发现使用purego更容易,他们的README示例工作:
package main import ( "fmt" "runtime" "github.com/ebitengine/purego" ) func getSystemLibrary() string { switch runtime.GOOS { case "darwin": return "/usr/lib/libSystem.B.dylib" case "linux": return "libc.so.6" default: panic(fmt.Errorf("GOOS=%s is not supported", runtime.GOOS)) } } func main() { libc, err := purego.Dlopen(getSystemLibrary(), purego.RTLD_NOW|purego.RTLD_GLOBAL) if err != nil { panic(err) } var puts func(string) purego.RegisterLibFunc(&puts, libc, "puts") puts("Calling C from Go without Cgo!") }
4条答案
按热度按时间wkyowqbh1#
在POSIX平台上,可以使用
cgo
调用dlopen和朋友:9lowa7mx2#
正如@JimB所说,你应该使用CGO,并将链接放在动态/静态库中。按照这个例子:
在此阅读更多信息:http://blog.golang.org/c-go-cgo
qkf9rpyu3#
@Martin Törnwall的答案解释了如何使用
dlopen()
进行函数查找。添加此答案以包括如何实际调用该函数的示例代码。(使用注解中建议的方法)。这个想法是用C语言为共享库中的每个函数编写一个 Package 器函数,它接受一个void* 指针(指向
dlopen()
返回的函数的指针),将其转换为适当的函数指针,然后调用它。假设我们在
libfoo.so
中有一个名为str_length
的函数来计算字符串的长度,那么得到的Go代码将是:fv2wmkja4#
发现使用purego更容易,他们的README示例工作: