首页 > 解决方案 > 将字节数组传递给插件函数

问题描述

我需要编写一个带有接受 golang 字节数组的函数的 golang 插件,但是当我在客户端代码中加载插件后尝试调用此函数时,它总是给我

恐慌:运行时错误:无效的内存地址或 nil 指针取消引用 [信号 SIGSEGV:分段违规代码 = 0x1 地址 = 0x18 pc = 0x40b22af]

关于如何解决这个问题的任何建议?

重现的代码(高度简化,但发生相同的错误)

客户端.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() {

}

标签: gopluginssegmentation-fault

解决方案


首先,您应该始终检查返回的错误(以及来自插件符号的类型断言的结果)!

您的问题是该sayHi()方法未导出。因此,如果您在应用程序中创建接口,它将与插件中创建的未导出方法不匹配。

导出该方法,它将起作用(假设您没有收到任何其他错误)。

在插件中:

func (d dummy) SayHi(data []byte) {
    log.Println("From plugin")
    log.Println(data)
}

在您的主应用程序中:

type T interface {
    SayHi(data []byte)
}

当调用它时:

b.SayHi(data)

这里要注意一件事。当您从插件中查找变量时,您会得到一个指向该变量的指针(否则您无法更改其值)。有关详细信息,请参阅:作为函数 return 的插件符号。这意味着symbol将是类型*dummy,而不是dummy。这在这里不会造成任何麻烦,因为方法集*dummy包含SayHi()方法,就像方法集一样dummy,但是如果您尝试对非接口类型(具体类型) 出一个插件符号。


推荐阅读