Golang中使用lua进行扩展
前言
最近在项目中需要使用lua进行扩展,发现github上有一个用golang编写的lua虚拟机,名字叫做gopher-lua.使用后发现还不错,借此分享给大家.
数据类型
lua中的数据类型与golang中的数据类型对应关系作者已经在文档中说明,值得注意的是类型是以L开头的,类型的名称是以LT开头的.
golang中的数据转换为lua中的数据就必须转换为L开头的类型:
str := "hello"
num := 10
L.LString(str)
L.LNumber(float64(num))
lua中的数据转换为golang中的数据,项目提供了ToInt,CheckString之类的函数来进行转换,但是这都是必须提前知道类型的,如果不知道就必须进行类型判断:
value := L.Get(1)
switch value.Type() {
case lua.LTString:
case lua.LTTable:
....
}
这里还可以使用gopher-luar来方便的进行类型转换.
golang和lua互相调用函数
golang中的函数必须转换为func(L *lua.State) int这种形式才能注入lua中,返回参数的int代表了返回参数的个数.
func hello(L *lua.State) int {
//将返回参数压入栈中
L.Push(lua.LString("hello"))
//返回参数为1个
return 1
}
//注入lua中
L.SetGlobal("hello", L.NewFunction(hello))
在golang中调用lua函数,lua脚本中需先定义这个函数,然后调用CallByParam进行调用:
//先获取lua中定义的函数
fn := L.GetGlobal("hello")
if err := L.CallByParam(lua.P{
Fn: fn,
NRet: 1,
Protect: true,
}, lua.LNumber(10)); err != nil {
panic(err)
}
//这里获取函数返回值
ret := L.Get(-1)
Table
关于lua中的table是一个很强大的东西,项目对table也提供了很多方法的支持比如获取一个字段,添加一个字段.这里推荐使用gluamapper,可以将tabl转换为golang中的结构体或者map[string]interface{}类型,这里使用了作者提供的例子:
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)
模块的加载与使用
项目中提供了lua基本模块,调用OpenLibs就可以加载这些模块,其中包括io,math,os,debug等.如果想自己加载可以使用SkipOpenLibs参数跳过.
如果想开发自己的库,文档中也做出了说明:
func Loader(L *lua.LState) int {
//注册模块中的导出函数
mod := L.SetFuncs(L.NewTable(), exports)
L.Push(mod)
return 1
}
var exports = map[string]lua.LGFunction{
"myfunc": myfunc,
}
func myfunc(L *lua.LState) int {
return 0
}
//这里就可以加载mymodule模块
L.PreloadModule("mymodule", mymodule.Loader)
Golang中使用lua进行扩展的更多相关文章
- C++中嵌入Lua脚本环境搭建
第一步(环境准备工作): 工具: ●LuaForWindows_v5.1.4-46.exe傻瓜式安装. 作用:此工具可以在windows环境下编译运行Lua脚本程序.安装完成后会有两个图标:Lua和S ...
- SLua 中使用 Lua 5.3 的编译工程
2016-03-05 更新: 之前编译的库,在 Android 下 Lua_Number 和 Lua_Integer 被编译为了32位,导致从 C# 到 Lua 过程中有64位到32位整型转换会出现溢 ...
- [转]Golang 中使用 JSON 的小技巧
taowen是json-iterator的作者. 序列化和反序列化需要处理JSON和struct的关系,其中会用到一些技巧. 原文 Golang 中使用 JSON 的小技巧是他的经验之谈,介绍了一些s ...
- golang中接口interface和struct结构类的分析
再golang中,我们要充分理解interface和struct这两种数据类型.为此,我们需要优先理解type的作用. type是golang语言中定义数据类型的唯一关键字.对于type中的匿名成员和 ...
- redis中使用lua脚本
lua脚本 Lua是一个高效的轻量级脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能 使用脚本的好处 1.减少网络开销,在Lua脚 ...
- 如何在Mac OS X 中运行Lua (Running Lua on Mac OS X)
参考文章:1) http://www.oschina.net/question/12_769552) http://rudamoura.com/luaonmacosx.html 最近在为iOS开发游戏 ...
- Golang 中的 面向对象: 方法, 类, 方法继承, 接口, 多态的简单描述与实现
前言: Golang 相似与C语言, 基础语法与C基本一致,除了广受争议的 左花括号 必须与代码同行的问题, 别的基本差不多; 学会了C, 基本上万变不离其宗, 现在的高级语言身上都能看到C的影子; ...
- 【协作式原创】查漏补缺之Golang中mutex源码实现(预备知识)
预备知识 CAS机制 1. 是什么 参考附录3 CAS 是项乐观锁技术,当多个线程尝试使用 CAS 同时更新同一个变量时,只有其中一个线程能更新变量的值,而其它线程都失败,失败的线程并不会被挂起,而是 ...
- Golang中如何正确的使用sarama包操作Kafka?
Golang中如何正确的使用sarama包操作Kafka? 一.背景 在一些业务系统中,模块之间通过引入Kafka解藕,拿IM举例(图来源): 用户A给B发送消息,msg_gateway收到消息后,投 ...
随机推荐
- ruby TkPackage can't find package BWidget 之解决办法
一个特别短的ruby/tk代码: require 'tkextlib\iwidgets' require 'tkextlib\bwidget' x = 0 101.times {|i| x+=i} T ...
- HTML DOM 实例
DOMAnchor 对象 更改一个链接的文本.URL 以及 target 使用 focus() 和 blur() 向超链接添加快捷键 Document 对象 使用 document.write() 向 ...
- java程序的内存分配(一)
首 页 阅览室 馆友 我的图书馆 帐号 java程序的内存分配(一) 收藏 JAVA 文件编译执行与虚拟机(JVM)介绍 Java 虚拟机(JVM)是可运行Java代码的假想计算机.只要根据J ...
- ORACLE中主键约束跟唯一索引的区别
分类: DB 2011-12-03 21:34 611人阅读 评论(0) 收藏 举报 oracleconstraintsimmutableusertabledomain 1. 分别用两种方法创建主键 ...
- IntelliJ IDEA下Cannot resolve symbol XXX的解决方法
Idea导入maven项目后,运行能通过,但是打开一些类后,会出现Cannot resolve symbol XXX的错误提示. 考虑几种可能: 1.JDK版本,设置JDK和Maven的JDK版本. ...
- redis分布式锁实践
分布式锁在多实例部署,分布式系统中经常会使用到,这是因为基于jvm的锁无法满足多实例中锁的需求,本篇将讲下redis如何通过Lua脚本实现分布式锁,不同于网上的redission,完全是手动实现的 我 ...
- Java编程语言下Selenium 对于下拉框,单选,多选等选择器的操作
WebElement selector = driver.findElement(By.id("Selector")); Select select = new Select(se ...
- Python高阶函数之 - 装饰器
高阶函数: 1. 函数名可以作为参数传入 2. 函数名可以作为返回值. python装饰器是用于拓展原来函数功能的一种函数 , 这个函数的特殊之处在于它的返回值也是一个函数 , 使用pyth ...
- C++:LIB和DLL的区别与使用
共有两种库: 一种是LIB包含了函数所在的DLL文件和文件中函数位置的信息(入口),代码由运行时加载在进程空间中的DLL提供,称为动态链接库dynamic link library. 一种是LIB包含 ...
- MySQL中遇到的几种报错及其解决方法
MySQL中遇到的几种报错及其解决方法 1.[Err] 1064 - You have an error in your SQL syntax; check the manual that corre ...