当前位置: 首页 > news >正文

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

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是要调用的全局函数名,Protecttrue时,如果没找到函数或者出错不会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)
}

相关文章:

  • yolov5+shufflenet轻量化目标检测
  • 【BurpSuite】插件开发学习之J2EEScan(上)-被动扫描
  • java计算机毕业设计企业公开招聘系统源码+数据库+系统+lw文档+mybatis+运行部署
  • 赛事开源Baseline参考目录格式
  • C++设计模式之Bridge桥模式
  • Kibana-8.4.0-Linux安装
  • @hook扩展分析
  • 利用 zabbix 监控服务端口
  • FastAPI 学习之路(二十九)使用(哈希)密码和 JWT Bearer 令牌的 OAuth2
  • 【愚公系列】2022年08月 微信小程序-纵向和横向选项卡功能实现
  • 猿创征文|Java实现自定义注解
  • 全网唯一OpenCyphal/UAVCAN教程(8)libcanard介绍
  • Redis的主从复制搭建
  • java毕业设计物资租赁管理系统mybatis+源码+调试部署+系统+数据库+lw
  • java计算机毕业设计评标专家管理信息系统源码+数据库+系统+lw文档+mybatis+运行部署
  • [译]Python中的类属性与实例属性的区别
  • 【162天】黑马程序员27天视频学习笔记【Day02-上】
  • CentOS 7 修改主机名
  • Java到底能干嘛?
  • macOS 中 shell 创建文件夹及文件并 VS Code 打开
  • vue从创建到完整的饿了么(11)组件的使用(svg图标及watch的简单使用)
  • Webpack入门之遇到的那些坑,系列示例Demo
  • windows下mongoDB的环境配置
  • 入门到放弃node系列之Hello Word篇
  • 问题之ssh中Host key verification failed的解决
  • Java数据解析之JSON
  • Java性能优化之JVM GC(垃圾回收机制)
  • 京东物流联手山西图灵打造智能供应链,让阅读更有趣 ...
  • ​2021半年盘点,不想你错过的重磅新书
  • ​flutter 代码混淆
  • ​业务双活的数据切换思路设计(下)
  • #快捷键# 大学四年我常用的软件快捷键大全,教你成为电脑高手!!
  • (2022版)一套教程搞定k8s安装到实战 | RBAC
  • (3)选择元素——(17)练习(Exercises)
  • (C++)八皇后问题
  • (Java数据结构)ArrayList
  • (Redis使用系列) SpringBoot中Redis的RedisConfig 二
  • (附源码)基于ssm的模具配件账单管理系统 毕业设计 081848
  • (免费领源码)Java#Springboot#mysql农产品销售管理系统47627-计算机毕业设计项目选题推荐
  • (十五)使用Nexus创建Maven私服
  • (算法二)滑动窗口
  • (学习日记)2024.01.09
  • (一)80c52学习之旅-起始篇
  • (一)搭建springboot+vue前后端分离项目--前端vue搭建
  • (转)菜鸟学数据库(三)——存储过程
  • (轉)JSON.stringify 语法实例讲解
  • .gitignore文件_Git:.gitignore
  • .NET Core 实现 Redis 批量查询指定格式的Key
  • .NET教程 - 字符串 编码 正则表达式(String Encoding Regular Express)
  • .NET开源项目介绍及资源推荐:数据持久层
  • @ConditionalOnProperty注解使用说明
  • @RequestMapping处理请求异常
  • [ C++ ] STL---string类的使用指南
  • [ HTML + CSS + Javascript ] 复盘尝试制作 2048 小游戏时遇到的问题
  • [Angular 基础] - 表单:响应式表单