【Go-Lua】Golang嵌入Lua代码——gopher-lua
有一种应用场景需要Lua调用Go语言的函数,例如数据处理过程中,需要发送一个异步HTTP请求,或者把数据插入到MySQL或者Redis,就可以调用Go的HTTP请求函数或数据库处理函数。Go调用Lua的函数最常用,Lua程序里定义函数和数据的处理方式,Go通过HTTP或者TCP获取到数据后,调用Lua的函数对数据处理,处理后,结果返回到Go语言,写入数据库或进行其他处理。Lua调用Go语言的函数就
Lua代码嵌入Golang
Go版本:1.19
首先是Go语言直接调用Lua程序,并打印,把环境跑通
package main
import lua "github.com/yuin/gopher-lua"
func main() {
L := lua.NewState()
defer L.Close()
// go
err := L.DoString(`print("go go go!")`)
if err != nil {
return
}
}
Lua的stdout可以直接转到go的stdout里,不过只调用打印一下没用意义,最重要的是函数调用
Go调用Lua的函数
Go调用Lua的函数最常用,Lua程序里定义函数和数据的处理方式,Go通过HTTP或者TCP获取到数据后,调用Lua的函数对数据处理,处理后,结果返回到Go语言,写入数据库或进行其他处理。
- Lua代码
function add(a,b)
return a+b
end
Lua支持多个参数和多个返回值,参数好办,用lua.LNumber(123)
类型有:
- LTNil
- LTBool
- LTNumber
- LTString
- LTFunction
- LTUserData
- LTThread
- LTTable
- LTChannel
返回值个数也可以是多个,调用CallByParam
的时候,NRet
就是返回参数个数,Fn是要调用的全局函数名,Protect
为true
时,如果没找到函数或者出错不会panic,只会返回err。
调用完成后,要以压栈的方式,一个一个取回返回值ret := L.Get(-1)
- Go代码
package main
import (
"fmt"
lua "github.com/yuin/gopher-lua"
)
func main() {
L := lua.NewState()
defer L.Close()
// go
err := L.DoFile("main.lua")
if err != nil {
fmt.Print(err.Error())
return
}
err = L.CallByParam(lua.P{
Fn: L.GetGlobal("add"),
NRet: 1,
Protect: true,
}, lua.LNumber(1), lua.LNumber(2))
if err != nil {
fmt.Print(err.Error())
return
}
ret := L.Get(-1)
// 如果是2个返回值, NRet改为2
// ret2 := L.Get(2)
// L.Pop(2)
L.Pop(1)
res, ok := ret.(lua.LNumber)
if ok {
fmt.Println(res)
}
}
Lua调用Go的函数
Lua调用Go语言的函数就没那么常用,因为虚拟机在Go语言程序里,需要传递数据直接通过Go的SetGlobal
或函数调用就可以了。
不过仍然有一种应用场景需要Lua调用Go语言的函数,例如数据处理过程中,需要发送一个异步HTTP请求,或者把数据插入到MySQL或者Redis,就可以调用Go的HTTP请求函数或数据库处理函数。
- Lua
print(add(10,20))
- Go
package main
import (
"fmt"
lua "github.com/yuin/gopher-lua"
)
func Add(L *lua.LState) int {
// 获取参数
arg1 := L.ToInt(1)
arg2 := L.ToInt(2)
ret := arg1 + arg2
// 返回值
L.Push(lua.LNumber(ret))
// 返回值的个数
return 1
}
func main() {
L := lua.NewState()
defer L.Close()
// 注册全局函数
L.SetGlobal("add", L.NewFunction(Add))
// go
err := L.DoFile("main.lua")
if err != nil {
fmt.Print(err.Error())
return
}
}
LuaTable转为GoStruct
package main
import (
"fmt"
"github.com/yuin/gluamapper"
lua "github.com/yuin/gopher-lua"
)
func main() {
type Role struct {
Name string
}
type Person struct {
Name string
Age int
WorkPlace string
Role []*Role
}
L := lua.NewState()
if err := L.DoString(`
person = {
name = "Michel",
age = "31", -- weakly input
work_place = "San Jose",
role = {
{
name = "Administrator"
},
{
name = "Operator"
}
}
}
`); err != nil {
panic(err)
}
var person Person
if err := gluamapper.Map(L.GetGlobal("person").(*lua.LTable), &person); err != nil {
panic(err)
}
fmt.Printf("%s %d", person.Name, person.Age)
}
更多推荐
所有评论(0)