繁体   English   中英

如何从插件的主应用程序调用 function?

[英]How do I call a function from the main application from a plugin?

我最近研究了Go 插件,而不是自己手动加载.so 文件。

基本上,我有一个游戏服务器应用程序,我希望能够在服务器启动时加载插件(使用插件包)。 然后,在插件本身中,我希望能够调用作为服务器一部分的导出函数。

假设我有这个插件,它使用go build -buildmode=plugin编译为example_plugin.so

package main

import "fmt"

func init() {
    fmt.Println("Hello from plugin!")
}

然后说我有这个服务器应用程序,它加载插件(并最终在引擎盖下调用“init”function):

package main

import (
    "fmt"
    "plugin"
)

func main() {
    fmt.Println("Server started")

    if _, err := plugin.Open("example_plugin.so"); err != nil {
        panic(err)
    }
}

// some API function that loaded plugins can call
func GetPlayers() {}

output 是:

Server started
Hello from plugin!

这可以按预期工作,但是我希望能够从插件(和任何其他插件)调用GetPlayers function (以及服务器应用程序中的任何其他导出函数,理想情况下)。我正在考虑制作某种由以下内容组成的库包含服务器实现的 API 函数的接口,但是我不知道从哪里开始。 我知道我可能需要使用 aa 文件或类似的东西。

为了澄清起见,我正在开发此应用程序以在 Linux 上使用,因此我对仅适用于 Linux 的解决方案很好。

抱歉,如果措辞不佳,这是第一次在 SO 上发帖。

正如评论中提到的,有一个查找 function。 在模块的文档中,他们有以下示例:

// A Symbol is a pointer to a variable or function.
// For example, a plugin defined as
//
// var V int
//
// func F() { fmt.Printf("Hello, number %d\n", V) }
//
// may be loaded with the Open function and then the exported package
// symbols V and F can be accessed

package main

import (
    "fmt"
    "plugin"
)

func main() {
    p, err := plugin.Open("plugin_name.so")
    if err != nil {
        panic(err)
    }
    v, err := p.Lookup("V")
    if err != nil {
        panic(err)
    }
    f, err := p.Lookup("F")
    if err != nil {
        panic(err)
    }
    *v.(*int) = 7
    f.(func())() // prints "Hello, number 7"
}

我认为这里最令人困惑的台词是

*v.(*int) = 7
f.(func())() // prints "Hello, number 7"

其中第一个对*int执行类型断言以断言v确实是指向int的指针。 这是必需的,因为Lookup返回一个interface{}并且为了对值做任何有用的事情,您应该澄清它的类型。

第二行执行另一种类型断言,这次确保f是一个 function 没有 arguments 并且没有返回值,之后立即调用它。 由于原始模块中的 function F引用了V (我们已将其替换为 7),因此此调用将显示Hello, number 7

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM