【Go-Lua】Golang嵌入Lua代码——gopher-lua

news/2025/1/11 3:52:23/

Lua代码嵌入Golang

Go版本:1.19
首先是Go语言直接调用Lua程序,并打印,把环境跑通

package mainimport lua "github.com/yuin/gopher-lua"func main() {L := lua.NewState()defer L.Close()// goerr := 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是要调用的全局函数名,Protecttrue时,如果没找到函数或者出错不会panic,只会返回err。

调用完成后,要以压栈的方式,一个一个取回返回值ret := L.Get(-1)

  • Go代码
    在这里插入图片描述
package mainimport ("fmt"lua "github.com/yuin/gopher-lua"
)func main() {L := lua.NewState()defer L.Close()// goerr := 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 mainimport ("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))// goerr := L.DoFile("main.lua")if err != nil {fmt.Print(err.Error())return}
}

LuaTable转为GoStruct

package mainimport ("fmt""github.com/yuin/gluamapper"lua "github.com/yuin/gopher-lua"
)func main() {type Role struct {Name string}type Person struct {Name      stringAge       intWorkPlace stringRole      []*Role}L := lua.NewState()if err := L.DoString(`person = {name = "Michel",age  = "31", -- weakly inputwork_place = "San Jose",role = {{name = "Administrator"},{name = "Operator"}}}
`); err != nil {panic(err)}var person Personif err := gluamapper.Map(L.GetGlobal("person").(*lua.LTable), &person); err != nil {panic(err)}fmt.Printf("%s %d", person.Name, person.Age)
}

http://www.ppmy.cn/news/809585.html

相关文章

浅谈如何使用 github.com/yuin/gopher-lua

1、 gopher-lua 基础介绍 我们先开看看官方是如何介绍自己的: GopherLua is a Lua5.1( goto statement in Lua5.2) VM and compiler written in Go. GopherLua has a same goal with Lua: Be a scripting language with extensible semantics . It provides Go AP…

Go分享好的github插件和项目

插件 QQ、微信(WeChat)、支付宝(AliPay)的Go版本SDK http://github.com/go-pay/gopay发送邮件库 https://github.com/go-gomail/gomail读写Microsoft Excel https://github.com/360EntSecGroup-Skylar/excelize生成uuid https://…

前后端分离项目问题总结

这里记录一下,我在写一个自己设计的项目时遇到的几个问题!!! 1、Session获取为null 需求:session保存验证码,在session中验证验证码是否正确 解释: 前端跨域访问后端接口, 在浏览器的安全策略…

申请和注销设备号的方法

一、Linux内核对设备的分类 linux的文件种类: -:普通文件 d:目录文件 p:管道文件 s:本地socket文件 l:链接文件 c:字符设备 b:块设备 Linux内核按驱动程序实现模型框架的不…

S3C2440 ARM920T CPU

S3C2440 ARM920T CPU 支持大端/小端模式。共同有8个存储器BANK,每个BANK为128M。BANK0~BANK6为固定起始地址。BANK7可编程BANK起始地址和大小,其开始地址是BANK6的结束地址,灵活可变。BANK0~BANK5用于ROM或者SRAM,BANK6、BANK7用…

linux驱动38:后备高速缓存

设备驱动程序常常会反复地分配同一大小的内存块&#xff0c;为这些反复使用的内存块增加某些特殊的内存池——后备高速缓存。 linux内核的高速缓存管理称为slab分配器&#xff0c;头文件<linux/slab.h>&#xff0c;类型struct kmem_cache。 一、api接口&#xff1a; 1…

socket简介及java实例

网络上的两个程序通过一个双向的通信连接实现数据的交换&#xff0c;这个连接的一端称为一个socket。 建立网络通信连接至少要一对端口号(socket)。socket本质是编程接口(API)&#xff0c;对TCP/IP的封装&#xff0c;TCP/IP也要提供可供程序员做网络开发所用的接口&#xff0c;…

三星ARM9以上芯片(244X,6410等)和cortex-a8芯片(S5PV210)比较PK

贴2张图&#xff0c;一看便明了&#xff1a;&#xff08;s5pv210开发技术交流群&#xff1a;8334819&#xff09; KEY FEATURES OF S5PV210 The key features of S5PV210 include: •ARM CortexTM-A8 based CPU Subsystem with NEON −32/ 32 KB I/D Cache, 512 KB L2 Cache −…