
[英]How call to main() function from main package is made despite being a private while starting an application?
[英]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.