[Go-Lua] Golang embedded Lua code - gopher-lua

Lua code embedded in Golang

Go version: 1.19
First, the Go language directly calls the Lua program and prints it to run through the environment

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's stdout can be directly transferred to go's stdout, but it's useless to just call and print, the most important thing is the function call

Go calls Lua functions

Go calls Lua functions most often. The Lua program defines the processing methods of functions and data. After Go obtains data through HTTP or TCP, it calls Lua functions to process the data. After processing, the results are returned to the Go language and written into the database or Do other processing.

  • Lua code
    insert image description here
function add(a,b)
    return a+b
end

Lua supports multiple parameters and multiple return values, the parameters are easy to handle, uselua.LNumber(123)

The types are:

  • LTNil
  • LTBool
  • LTNumber
  • LTString
  • LTFunction
  • LTUserData
  • LTThread
  • LTTable
  • LTChannel

The number of return values ​​can also be multiple. When calling CallByParam, NRetit is the number of return parameters. Fn is the name of the global function to be called. ProtectIftrue the function is not found or an error occurs, it will not panic, and only err will be returned.

After the call is completed, the return value should be retrieved one by one by pushing the stackret := L.Get(-1)

  • Go code
    insert image description here
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 calls Go functions

SetGlobalIt is not so common for Lua to call Go language functions, because the virtual machine needs to transfer data directly through Go or function calls in the Go language program .

However, there is still an application scenario that requires Lua to call functions in the Go language. For example, during data processing, if you need to send an asynchronous HTTP request, or insert data into MySQL or Redis, you can call Go’s HTTP request function or database processing function.

  • 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 to 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)
}

Guess you like

Origin blog.csdn.net/xuehu96/article/details/126613678
Recommended