github.com/yuin/gopher-lua 踩坑日记
本文主要记录下在日常开发过程中, 使用 github.com/yuin/gopher-lua 过程中需要注意的地方。
后续遇到其他的需要注意的事项再补充。
1、加载LUA_PATH环境变量
在实际开发中,我们会将一些公共的、可重复使用的代码封装起来,假如我们只是一些简单的处理,全部写在一个文件是没有问题的,维护起来也并不是很麻烦。但是当我们的需求变得复杂起来,或者需求调整的时候,我们还是将所有功能都写在同一个文件的时候,就变得不合理起来,后期的维护更是灾难性的,这个时候就需要将一些公共的、重复使用的代码,抽离出来,根据功能的不同分类,当做一个个模块,在使用的时候使用 require 导入进来,这样才合理。
既然我们需要将自定义的 module 导入进来,那么我们肯定是需要设计环境变量的。
最重要的地方就是下面这点:
// 重点就是这句, 先设置环境变量, 再创建 lua 的 虚拟机, 这样环境变量才生效!!!
setLuaLibPath()
lvm := newLuaVm(pluginPath, context.Background())
接下来再详细看演示的demo。
先看看代码目录分层,有一个整体认识。
--go_call_lua_test
|---go.mod
|---main.go
|---plugin.lua
|---lib/lua/test.lua
main.go 代码
package main
import (
"context"
"errors"
"fmt"
lua "github.com/yuin/gopher-lua"
"go.uber.org/atomic"
luar "layeh.com/gopher-luar"
"os"
"path/filepath"
)
func getExeDir() (string, string) {
exePath, _ := os.Executable()
exeDir, exeName := filepath.Split(exePath)
return exeDir, exeName
}
func absPath(fp string) string {
exeAbsDir, _ := getExeDir()
//绝对路径
if !filepath.IsAbs(fp) {
return filepath.Join(exeAbsDir, fp)
} else {
return fp
}
}
func setLuaLibPath() {
//设置lua环境变量
pathStr := ""
LuaLibPath := []string{"./lib/lua/?.lua"}
for _, path := range LuaLibPath {
pathStr += ";" + absPath(path)
}
pathStr += ";;"
os.Setenv("LUA_PATH", pathStr)
}
type LuaVm struct {
*lua.LState
path string
Loaded atomic.Bool
}
func newLuaVm(path string, ctx context.Context) *LuaVm {
lv := &LuaVm{
path: path,
LState: lua.NewState(),
}
lv.SetContext(ctx)
if err := lv.load(); err != nil {
panic(fmt.Errorf("lvm error=%s", err))
}
return lv
}
func (lv *LuaVm) load() error {
//加载工具 下面是将 go 提供的功能当做模块 给 lua 使用
//lv.SetGlobal("FILE", luar.New(lv.LState, &test.FileTool{}))
if len(lv.path) == 0 {
return fmt.Errorf("plugin file empty")
}
if err := lv.DoFile(lv.path); err != nil {
return err
}
lv.Loaded.Store(true)
return nil
}
func (lv *LuaVm) CallLua() (result string, err error) {
if err := lv.CallByParam(lua.P{
Fn: lv.GetGlobal("PluginTest"),
NRet: 2,
Protect: true,
}, luar.New(lv.LState, "I'm coming go!")); err != nil {
fmt.Printf("PrimaryIn error=%s", err)
}
retCode, _ := lv.Get(-1).(lua.LNumber)
lv.Pop(1)
retPkt, _ := lv.Get(-1).(lua.LString)
lv.Pop(1)
if retCode != 0 {
return "", errors.New("untreated")
}
return string(retPkt), nil
}
func main() {
pluginPath := "./plugin.lua"
// 重点就是这句, 先设置环境变量, 再创建 lua 的 虚拟机, 这样环境变量才生效!!!
setLuaLibPath()
lvm := newLuaVm(pluginPath, context.Background())
ret, err := lvm.CallLua()
fmt.Println("ret --> ", ret)
fmt.Println("err --> ", err)
}
plugin.lua 代码
local TestLib = require("test")
function PluginTest()
print("coming PluginTest")
TestLib.CallTestFunc()
return "I'm coming lua!"
end
test.lua 代码
justTest = {}
function justTest.CallTestFunc()
print("coming justTest.CallTestFunc")
end
-- 一定要 return, 否则不生效
return justTest
编译后执行结果:
coming PluginTest
coming justTest.CallTestFunc
ret --> I'm coming lua!
err --> <nil>
github.com/yuin/gopher-lua 踩坑日记的更多相关文章
- AI相关 TensorFlow -卷积神经网络 踩坑日记之一
上次写完粗浅的BP算法 介绍 本来应该继续把 卷积神经网络算法写一下的 但是最近一直在踩 TensorFlow的坑.所以就先跳过算法介绍直接来应用场景,原谅我吧. TensorFlow 介绍 TF是g ...
- 人工智能(AI)库TensorFlow 踩坑日记之一
上次写完粗浅的BP算法 介绍 本来应该继续把 卷积神经网络算法写一下的 但是最近一直在踩 TensorFlow的坑.所以就先跳过算法介绍直接来应用场景,原谅我吧. TensorFlow 介绍 TF是g ...
- hexo博客谷歌百度收录踩坑日记
title: hexo博客谷歌百度收录踩坑日记 toc: false date: 2018-04-17 00:09:38 百度收录文件验证 无论怎么把渲染关掉或者render_skip都说我的格式错误 ...
- Hexo搭建静态博客踩坑日记(二)
前言 Hexo搭建静态博客踩坑日记(一), 我们说到利用Hexo快速搭建静态博客. 这节我们就来说一下主题的问题与主题的基本修改操作. 起步 chrome github hexo git node.j ...
- Hexo搭建静态博客踩坑日记(一)
前言 博客折腾一次就好, 找一个适合自己的博客平台, 专注于内容进行提升. 方式一: 自己买服务器, 域名, 写前端, 后端(前后分离最折腾, 不分离还好一点)... 方式二: 利用Hexo, Hug ...
- React Native Android配置部署踩坑日记
万事开头难 作为一只进入ECMAScript世界不久的菜鸟,已经被React Native的名气惊到了,开源一周数万星勾起了我浓烈的兴趣.新年新气象,来个HellWorld压压惊吧^_^(故意少打个' ...
- 人工智能(AI)库TensorFlow 踩坑日记之二
上次 踩坑日志之一 遗留的问题终于解决了,所以作者(也就是我)终于有脸出来写第二篇了. 首先还是贴上 卷积算法的示例代码地址 :https://github.com/tensorflow/models ...
- JavaScript 新手的踩坑日记
引语 在1995年5月,Eich 大神在10天内就写出了第一个脚本语言的版本,JavaScript 的第一个代号是 Mocha,Marc Andreesen 起的这个名字.由于商标问题以及很多产品已经 ...
- 一次从Github向Gitee迁库踩坑记录
先上结论:gitee的lfs功能收费,直接从github迁移包含lfs管理的文件会出错,配置lfs.url即可解决问题 Q: 为什么要迁库呢? A: github访问太慢了,不然我也不想费这个功夫! ...
- React Native踩坑日记 —— tailwind-rn
项目背景 在项目的初始阶段,我们需要建立自己的design system,我们spike了一些方案,tailwind-rn就是其中一种,如果有用到或者即将用到tailwind-rn的,可以进来看一看, ...
随机推荐
- Solon v2.2.17 发布,Java 新的生态型应用开发框架
相对于 Spring Boot 和 Spring Cloud 的项目: 启动快 5 - 10 倍. (更快) qps 高 2- 3 倍. (更高) 运行时内存节省 1/3 ~ 1/2. (更少) 打包 ...
- 关于ESXi下如何查看磁盘SMART信息(SATA & NVMe)的教程
ESXi下查看磁盘SMART比较麻烦,并且SATA协议的和NVMe协议的操作不一样,下面分别进行详细陈述 SATA--使用smartctl查看 本部分参考梦幻生命@CSDN(原文链接https://b ...
- 程序员的 Windows 工具箱「GitHub 热点速览」
如何精简 Windows 并快速配置开发环境呢?本周特推的 winutil 是一个程序员的 Windows 工具箱,它提供了开发工具的一键安装以及减少系统垃圾的功能,一切为了简洁.高效.同样高效的还有 ...
- SQL后半部和JDBC
SQL后半部 排序order by asc 升序desc 降序select *from 表名 order by 列名 asc ; select *from 表名 order by 列名 asc , 列 ...
- Ubuntu 对比 CentOS 后该如何选择?
大家阅读完以上文章觉得如何选择更适合自己?欢迎留言哦~ 本文章转载自 Linux 就该这么学(ID: linuxprobe),文章图片与文字版权属源公众号所有,未经允许,禁止二次转载. 我要投稿 本公 ...
- C++面试八股文:在C++中,有哪些可执行体?
某日二师兄参加XXX科技公司的C++工程师开发岗位第14面: 面试官:在C++中,有哪些可执行体? 二师兄:可执行体? 面试官:也就是可调用对象. 二师兄:让我想一想.函数.函数指针.类的静态方法.类 ...
- Hugging News #0616: 有几项非常重要的合作快来围观、最新中文演讲视频回放发布!
每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...
- 【Java技术专题】「攻破技术盲区」带你攻破你很可能存在的Java技术盲点之动态性技术原理指南(反射技术专题)
@ 目录 带你攻破你很可能存在的Java技术盲点之动态性技术原理指南 编程语言的类型 静态类型语言 动态类型语言 技术核心方向 反射API 反射案例介绍 反射功能操作 获取构造器 长度可变的参数 - ...
- C++ 核心指南之资源管理(上)
C++ 核心指南(C++ Core Guidelines)是由 Bjarne Stroustrup.Herb Sutter 等顶尖 C++ 专家创建的一份 C++ 指南.规则及最佳实践.旨在帮助大家正 ...
- 发布一个Visual Studio 2022 插件,可以自动完成构造函数依赖注入代码
赖注入(DI)在开发中既是常见的也是必需的技术.它帮助我们优化了代码结构,使得应用更加灵活.易于扩展,同时也降低了各个模块之间的耦合度,更容易进行单元测试,提高了编码效率和质量.不过,手动注入依赖项也 ...