我需要编写一个 golang 插件,其中包含一个接受 golang 字节数组的函数,但是当我在客户端代码中加载插件后尝试调用此函数时,它总是给我
panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x40b22af]
关于如何解决这个问题有什么建议吗?
重现代码(高度简化,但出现相同的错误)
client.go
package main
import (
"plugin"
"log"
)
type T interface {
sayHi(data []byte)
}
func main() {
plgin, _ := plugin.Open("./plugin.so")
symbol, _ := plgin.Lookup("Endpoint")
b, _ := symbol.(T)
log.Println("From main")
data := []byte{1,2,3,4,5}
b.sayHi(data)
}
plugin.go(该程序是使用buildmode=plugin
构建的)
package main
import (
"log"
)
type dummy struct {}
func (d dummy)sayHi(data []byte) {
log.Println("From plugin")
log.Println(data)
}
var Endpoint dummy
func main() {
}
最佳答案
首先,您应该始终检查返回的错误(以及插件符号的类型断言的结果)!
您的情况的问题是 sayHi()
方法未导出。因此,如果您在应用程序中创建接口(interface),它将与插件中创建的未导出方法不匹配。
导出该方法,它将起作用(前提是您没有收到任何其他错误)。
在插件中:
func (d dummy) SayHi(data []byte) {
log.Println("From plugin")
log.Println(data)
}
在您的主应用程序中:
type T interface {
SayHi(data []byte)
}
调用时:
b.SayHi(data)
这里需要注意一件事。当您从插件查找变量时,您将获得指向该变量的指针(否则您无法更改其值)。详情参见:Plugin symbol as function return 。这意味着 symbol
的类型将为 *dummy
,而不是 dummy
。这不会在这里造成任何麻烦,因为 method set *dummy
也包含 SayHi()
方法,就像 dummy
的方法集一样,但如果你想的话,你不应该忘记这一点尝试从插件符号中类型断言非接口(interface)类型(具体类型)。
关于go - 将字节数组传递给插件函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51395930/