美文网首页
Lua学习笔记-Day05

Lua学习笔记-Day05

作者: 陈振拥 | 来源:发表于2015-07-24 15:44 被阅读0次

1、编写供lua调用的C函数

编写一个C函数返回一个table,简单示例代码如下:

//返回一个table
static int l_getmytable(lua_State * L)
{
    lua_newtable(L);
    char str[20] = {0};
    for(int i = 1; i <= 10; i++)
    {
        lua_pushnumber(L,i);//相当于压入key
        sprintf(str, "num is : %d", i);
        lua_pushstring(L,str);//压入value
        lua_settable(L, -3);//将前面的key和value都保存到table中
    }
    return 1;
}

//将l_getmytable函数公开给Lua

static void register_my_functions(lua_State* L)
{
    lua_pushcfunction(L,l_getmytable);
    lua_setglobal(L,"getmytable");
}

int main()
{
    lua_State *ll = luaL_newstate();
    luaL_openlibs(ll);
    register_my_functions(ll);
    luaL_dofile(ll, "call_C.lua");
    lua_close(ll);
    return 0;
}

在call_C.lua文件中调用getmytable函数如下:

local t = getmytable()
for k, v in pairs(t) do
    print(k,v)
end

运行结果如下:

运行结果正常输出了一个table中的key和value。

2、编写一个供Lua调用的C模块。

在lualib项目下的源文件下找到init.c文件

在init.c中编写可供Lua调用的函数,简单示例代码如下:

//可供Lua调用函数1
static int showRlt1(lua_State * L)
{
    lua_pushstring(L,"Im showRLT1");
    return 1;
}
//可供Lua调用函数2
static int showRlt2(lua_State * L)
{
    const char * value = luaL_checkstring(L, -1);
    lua_pushstring(L,value);
    return 1;
}

接着注册一下上面两个函数,实际上就是注册一个结构体数组mylibs(mylibs就是要供Lua调用的C模块):

static const luaL_Reg mylibs[] = {
            {"rlt1",showRlt1},//showRlt1函数注册为rlt1,即在Lua中调用这个函数时使用人rlt1
            {"rlt2",showRlt2},//showRlt2函数注册为rlt2,即在Lua中调用这个函数时使用人rlt2
            {NULL,NULL}
        };

利用上面的结构体数组创建lib:

int luaopen_my_lib(lua_State * L)
{
    luaL_newlib(L,mylibs);
    return 1;
}

然后再init.c文件的结构体数组loadedlibs中加入{"mylibs", luaopen_my_lib}一项:

最后重新生成lualib项目,以使新的模块加到lualib库中:

接下来是在Lua中调用mylibs模块,在call_C.lua文件中编写语句如下:

local mylib = require("mylibs")--引入mylibs模块
print(mylib)--实际结果为一个table

print(mylib.rlt1())--调用mylibs模块中的rlt1函数,实际调用的是init.c文件中的showRlt1函数
print(mylib.rlt2("chenzhenyong"))--调用mylibs模块中的rlt2函数,实际调用的是init.c文件中的showRlt2函数

运行程序,结果如下 :

3、Lua中的线程和状态

lua_State *ll = lua_newthread(luaState);//在当前线程中创建了一个新线程
        //创建了新线程实际上就是在当前状态下创建了一个新状态。创建完的同时将子线程压入栈顶。
    //最后将新线程即新状态返回
    lua_pop(luaState, 0);//这会把栈顶的子线程弹出,之后子线程不在存在。
    //注意子线程的创建依赖于现有的线程。

4、Lua中内存管理方式。Lua 对其内存具有严格控制,当关闭一个Lua状态时,Lua会显式地释放它的所有内存。如果加载了一个很大的Lua模块,并在之后删除了所有对它的引用,Lua最终会回收这个模块使用的所有没存。Lua通过一个“分配函数”来完成所有的你内存分配和释放,当用户创建一个Lua状态时,必须提供这个函数。

Lua中的垃圾回收器。从第一版到5.0版本,采用一种简单的“标记并清扫”垃圾收集器。Lua有时候会为了完成一个完整的垃圾收集周期而暂停与主程序的交互。每个垃圾收集周期分为4个阶段,标记、整理、清扫和收尾。

标记阶段:将所有可到达的对象都标记为活跃。

整理阶段:整理userdata。删除未被标记的key和value。

清扫阶段:遍历所有对象,未标记的就收集,已标记的就清除标记。

收尾阶段:更具整理阶段生成的userdata列表来调用它们的终结函数。

Lua5.1开始使用一种增量式的收集器,步骤与原收集器一样,但是它当的运行不会暂停整个程序的相应。它以隔行扫描的方式与解释器一起工作,每当解释器分配了一些固定的内存后,收集器就会运行一小步。在增量式的收集器中增加了原子操作。

相关文章

  • Lua学习笔记-Day05

    1、编写供lua调用的C函数 编写一个C函数返回一个table,简单示例代码如下: //返回一个tablestat...

  • 2021-08-06_lua脚本学习笔记

    20210806_lua脚本学习笔记 1概述 1.1为什么lua脚本具有原子性 Redis保证以原子方式执行脚本,...

  • 2022-05-02_Lua脚本操作redis锁学习笔记

    20220502_Lua脚本操作redis锁学习笔记.md 1概述 释放锁要用 lua 脚本,把检查锁是不是本线程...

  • 2019-01-14

    Lua与C交互学习笔记 Lua与C交互是通过虚拟栈实现的 在C中调用Lua 方法一 栈中的情况如下表所示 方法二 ...

  • Lua学习笔记

    函数调用: lua函数在两种情况下,可以省略’()’:函数中参数是一个单独的字符串或者表。因此,myfunc{a=...

  • Lua 学习笔记

    1. dummy variables(虚变量) Usually,I reserve the identifier ...

  • Lua学习笔记

    1.元表中的算术操作符对应字段 __add:加法__sub:减法__union:整合去重__dev:除法__unm...

  • Lua学习笔记

    参考Lua 5.3 参考手册Lua 5.1 参考手册云风的blogLua开发者论坛Pogramming in Lu...

  • lua学习笔记

    最近项目要用的lua 所以抽空学习 记录一下 IDE有ZeroBrane Studio 我还是用的sublime...

  • Lua 学习笔记

    最近要用到 Lua 编程语言,所以学习了一些简明教程,同时记录一下 Lua 编程语言相对于其他主流编程语言在语法上...

网友评论

      本文标题:Lua学习笔记-Day05

      本文链接:https://www.haomeiwen.com/subject/rhfmqttx.html