lua luna工具库

luna工具库

概述

luna库提供了几个lua开发的常见辅助功能:

  • lua/c++绑定
  • lua序列化与反序列化
  • 变长整数编码,用于lua序列化,当然也可以方便的用于其他场合

这里把代码编译成了动态库,由于代码非常简单,实际使用时也可以简单的复制文件到自己的工程.
lua_archiver引用了lz4库用于数据压缩(lz4.h+lz4.c).

lua/c++绑定库(luna.h, luna.cpp)支持Windows, Linux, macOS三平台,默认的luna.h实现需C++14支持.
如果编译器不支持C++14,也可以将其替换为C++11版本的luna11.h.
之所以实现这个lua/c++绑定,是出于以下的想法:

  • 希望所有事情在c++代码中就搞定,不希望额外再运行一个什么转换处理工具
  • 希望能够方便的导出一般C++函数,而不必写一大堆lua api调用代码
  • 希望能简单的处理导出对象的生命期
  • 希望能方便的在lua代码中对导出对象进行扩展,重载等
  • 希望使用尽可能简单,无需对luna库本身做任何初始化
  • 希望执行时无副作用,即没有全局或静态的数据,进程中存在多个lua_State时不会相互干扰

编译说明

luna同时支持Windows, Linux, MacOS三平台,编译器最低必须支持C++11,最好支持C++14,需要安装cmake.
在编译之前,应先编译安装lua,然后:

cd luna
mkdir build
cd build
cmake ..
make

在macos上,可能会遇到编译器默认没有搜索/usr/local/include 目录而导致找不到lua.hpp的问题.
解决办法是执行xcode-select --install,该命令不仅仅是安装命令行工具,还会设置相应的参数.

除了编译为动态库,也可以简单的将源码复制到工程中使用,如果打算这样用,那么注意:
luna.h并不直接存在,而是cmake根据编译环境选取的luna14.h或者luna11.h,你可以根据自己的环境选择即可.

C++导出全局函数

当函数的参数以及返回值是***基本类型***或者是***已导出类***时,可以直接用lua_register_function导出:

int func_a(const char* a, int b);
int func_b(my_export_class_t* a, int b);
some_export_class* func_c(float x);

lua_register_function(L, func_a);
lua_register_function(L, func_b);
lua_register_function(L, func_c);

当然,你也可以导出lua标准的C函数.

导出类

首先需要在你得类声明中插入导出声明:

class my_class final
{
    // ... other code ...
    int func_a(const char* a, int b);
    int func_b(some_class_t* a, int b);
    char m_name[32];
public:
    // 插入导出声明:
    DECLARE_LUA_CLASS(my_class);
};

在cpp中增加导出表的实现:

EXPORT_CLASS_BEGIN(my_class)
EXPORT_LUA_FUNCTION(func_a)
EXPORT_LUA_FUNCTION(func_b)
EXPORT_LUA_STRING(m_name)
EXPORT_CLASS_END()

可以用带_AS的导出宏指定导出的名字,用带_R的宏指定导出为只读变量. 比如: EXPORT_LUA_STRING_AS(m_name, Name)

关于导出类(对象)的注意点

目前通过静态断言作了限制: 只能导出声明为final的类

这是为了避免无意间在父类和子类做出错误的指针转换 如果需要父类子类同时导出且保证不会出现这种错误,可以自行去掉这个断言

关于C++导出对象的生存期问题

注意,C++对象一旦被push进入lua,其生命期就交给lua的gc管理了,C++层面不能随便删除. 这些lua托管的对象在gc时,会默认调用delete,如果不希望调用delete,可以在对象中实现自定义gc方法: void __gc().   另外,由于lua的gc回收资源总是具有一定延迟的,所以如果C++对象持有较多的资源的话,最好显示释放资源或者在lua层面显示的调用gc.
对于已经push到lua的对象,如果想从C++解除引用,可以调用lua_detach(L, object);

class my_class final
{
    // ...
public:
    DECLARE_LUA_CLASS(my_class);
    void __gc()
    {
        // lua gc时,如果存在本函数,那么会调用本函数取代默认的delete
    }
};

lua中访问导出对象

lua代码中直接访问导出对象的成员/方法即可.

local obj = get_obj_from_cpp();
obj.func("abc", 123);
obj.name = "new name";

另外,C++对象导出到lua中是通过一个table来实现的,可以称之为影子对象. 不但可以在lua中访问C++对象成员,还可以有下面这些常见用法:

  • 重载(覆盖)对象上的C++导出方法.
  • 在影子对象上增加额外的成员变量和方法.
  • 在C++中调用lua中为对象增加的方法,参见lua_call_object_function.

C++中调用lua函数

目前提供了两种支持:

  • C++调用全局函数
  • C++调用全局table中的函数
  • C++调用导出对象上附加的函数.

下面以调用全局table中的函数为例:

function s2s.some_func(a, b)
    return a + b, a - b, "tom";
end

上面的lua函数返回三个值,那么,可以在C++中这样调用:

lua_guard g(L); //用它来做栈保护
int x, y;
const char* name = nullptr;
// 小心,如果用char*做字符串返回值的话,确保name变量不要在lua_guard g的作用域之外使用
lua_call_table_function(L, nullptr, "s2s", "some_func", std::tie(x, y, name), 11, 2);

注意上面的lua_guard,它实际上做的事情是:

  1. 在构造时调用lua_gettop保存栈.
  2. 析构时调用lua_settop恢复栈.
// 注意这里由于需要传入abc三个参数,所以需要写一个std::tie()表示没有返回参数
lua_call_table_function(L, nullptr, "s2s", "some_func", std::tie(), a, b, c);

如果没有参数,也没有返回值,那就是最简单的写法了:

lua_call_table_function(L, nullptr, "s2s", "some_func");

原文地址:https://www.cnblogs.com/decode1234/p/9007193.html

时间: 2024-10-09 06:39:53

lua luna工具库的相关文章

使用Lua的扩展库LuaSocket用例

目录结构 LuaSocket 是 Lua 的网络模块库,它可以很方便地提供 TCP.UDP.DNS.FTP.HTTP.SMTP.MIME 等多种网络协议的访问操作. 它由两部分组成:一部分是用 C 写的核心,提供对 TCP 和 UDP 传输层的访问支持.另外一部分是用 Lua 写的,负责应用功能的网络接口处理. 一.安装LuaSocket 下面介绍两种安装方法 第一种方法:如果你有安装了 Lua 模块的安装和部署工具 LuaRocks,那么一条指令就能安装部署好 LuaSocket: # lua

js常用工具库XCLJsTool v1.0发布

最近有空,整了一个js的工具库,还没有正式用于项目中,自己也没有时间写测试用例,想了一下,还是贴出来给大家看看,如果有问题,请留言,非常感谢!项目我放在了github上面,会经常更新的,过段时间会发布一版! /** * 欢迎使用本程序,您可以任意修改.复制.分享本程序所有代码,只需要保留本注释即可,谢谢! * 项目地址:<span style="color:#ff0000;">https://github.com/xucongli1989/XCLJsTool</spa

FunDA:一个开源的函数式数据处理工具库,也是Slick的补充

如果你是一个Slick用户,或者你是一个数据库编程人员正在尝试进入函数式编程模式,那么FunDA可能会帮到你. 目前市面上FRM(Functional Relational Mapper),即函数式的数据库处理工具库的选择并不多,Typesafe公司的Slick可能是最通用的选择了.整体上来说:Slick还是一个不错的函数式数据库编程工具,用scala语言,很多地方引用了函数式的抽象模式和对象(functional abstractions and objects).但是,FRM是一种偏重数据读

JS工具库之Lodash

破狼 JavaScript工具库之Lodash 2015-04-11 16:08 by 破狼, 235 阅读, 2 评论, 收藏, 编辑 你还在为JavaScript中的数据转换.匹配.查找等烦恼吗?一堆看似简单的foreach,却冗长无趣,可仍还在不停的repeat it!也许你已经用上了Underscore.js,不错,你已经进步很大一步了.然而今天我希望你能更进一步,利用lodash替换掉Underscore. lodash一开始是Underscore.js库的一个fork,因为和其他(U

Bean-Query 一个把对象转换为Map的Java工具库

刚开源了一个经过完整测试的Java工具类.目前的代码已经经历了完整的测试,正在申请放到Maven central Repository上. 地址如下: https://github.com/Jimmy-Shi/bean-query 使用说明如下: Bean-query Click Here for English version. BeanQuery 是一个把对象转换为Map的Java工具库.支持选择Bean中的一些属性,对结果进行排序和按照条件查询.不仅仅可以作用于顶层对象,也可以作用于子对象

Android高手速成--第二部分 工具库

主要包括那些不错的开发库,包括依赖注入框架.图片缓存.网络相关.数据库ORM建模.Android公共库.Android 高版本向低版本兼容.多媒体相关及其他. 一.依赖注入DI 通过依赖注入减少View.服务.资源简化初始化,事件绑定等重复繁琐工作 AndroidAnnotations(Code Diet)android快速开发框架项目地址:https://github.com/excilys/androidannotations文档介绍:https://github.com/excilys/a

Android 绘图工具库AChartEngine

From: http://www.oschina.net/p/achartengine AChartEngine是为android应用而设计的绘图工具库.目前该库的最新稳定版本是0.7,支持绘制以下类型的图表: line chart area chart scatter chart time chart bar chart pie chart bubble chart doughnut chart range (high-low) bar chart dial chart / gauge com

Lua中字符串库中的几个重点函数

前言 在<Lua中的一些库>中也说道了,要对string库的模式匹配进行单独的讲解.对于字符串的处理,对于任何语言的学习来说,都是一个难点,而且也是一个必会的知识点.给你一个字符串,让你按照某种需求进行处理,你不会,那是多么尴尬的一件事情.所以,看完<Lua中的一些库>和这篇文章之后,我争取做到让你在处理字符串时,不再感到捉襟见肘,不再尴尬. 说到Lua中的模式匹配,基本上就是围绕着以下几个函数展开的: find match gsub gmatch 我的总结也就是围绕着上面的四个函

Lua整理——table库

table属性 table库是有一些辅助函数构成的,这些函数将table作为数组来操作.其中,有对列表中插入和删除元素的函数,有对数组元素进行排序的函数,还有对链接一个数组中所有字符串的函数. 0.table.getn()Lua 中我们经常假定 array 在最后一个非 nil 元素处结束. 这个传统的约定有一个弊端:我们的 array中不能拥有 nil 元素.对大部分应用来说这个限制不是什么问题,比如当所有的 array 有固定的类型的时候.但有些时候我们的 array 需要拥有 nil 元素