zoukankan      html  css  js  c++  java
  • 一种Lua到C的封装

    一种Lua到C的封装

     

    在Lua的官方C API中,Lua与C通过一个虚拟栈来交互数据。例如有个a.lua的文件中有求和函数:

    function sum(a, b)
        return a + b
    end

    要在C代码中打开lua文件,并调用求和函数,大致要这样写:

    复制代码
    lua_State *s = luaL_newstate();
    luaL_openlibs(s);
    luaL_loadfile(s, "a.lua");
    lua_getglobal(s, "sum");
    lua_pushinteger(s, 1234);
    lua_pushinteger(s, 4321);
    lua_pcall(s, 2, 1, 0);
    int sum = lua_tointeger(s, -1); /* sum = 5555 */
    lua_pop(s, 1);
    lua_close(s);
    复制代码

    可以想见官方API的设计专注于正交性,而不考虑便利性。

    自然希望有一个封装,让程序员在C代码中,尽可能地像Lua一样调用Lua。

    github上没搜到特别中意的,只好自己写一个,取名Lucy。设计目标:

    1) 隐藏虚拟栈——因此也隐藏基于虚拟栈的官方C API。

    2) 在C代码中,尽量用Lua的方式调用Lua代码。

    3) function和table在C代码中也该是第一类型,可以作为函数参数传递——其实是第2) 点的补充说明。

    在Lua这样的动态类型语言中,变量本身没有类型,被赋值后才有相应的类型。

    因此在Lucy中只需定义一个名为lucy_Data的结构体用以表示Lua变量:

    复制代码
    typedef struct {
        lucy_Type type_;
        lucy_Content cntnt_;
    } lucy_Data;
    复制代码

    lucy_Type是一个枚举类型,lucy_Content则是联合体。

    如此定义,则对lucy_Data作任何操作,编译期都没问题,而只会在运行期断言失败,算是对Lua变量的模拟。

    lucy_Content中有个类型lucy_Ref:

    复制代码
    typedef struct {
        lua_State *state_;
        int index_;
    } lucy_Ref;
    复制代码

    保存function, table这样的引用类型,在虚拟栈上的索引。于是它们就可以作为第一类型了。

    function传入参数,传出返回值的基础类型,都可以是lucy_Data的数组类型lucy_List。

    不难设计与实现剩下的接口。

    例如有以下Lua代码:

    复制代码
    function Loc(x, y)
        return function() return x, y end
    end
    
    function GetArea(loc)
        local x, y = loc()
        return x * y
    end
    复制代码

    给定x与y,通过调用GetArea函数来取得结果,通过Lucy封装后可以这么写(比如x与y都为5):

    复制代码
    lucy_File file = lucy_CreateFile();
    lucy_OpenFile(&file, "a.lua");
    lucy_Data Loc = lucy_GetData(&file, "Loc");
    lucy_Data five = lucy_Num(5);
    lucy_Data loc = lucy_Call(&Loc, 1, 2, &five, &five).datas_[0];
    lucy_Data GetArea = lucy_GetData(&file, "GetArea");
    lucy_Data area = lucy_Call(&GetArea, 1, 1, &loc).datas_[0];
    
    lucy_PrintData(&area);
    复制代码

    运行结果:

    代码已上传至: https://github.com/chncwang/Lucy

    已有的接口包括取变量,调用function,查询table元素,长度等。

     
    分类: Lua
  • 相关阅读:
    macbook 无声音解决方案
    webapck dev server代理请求 json截断问题
    百度卫星地图开启
    服务器 nginx配置 防止其他域名绑定自己的服务器
    记一次nginx php配置的心路历程
    遇到npm报错read ECONNRESET怎么办
    运行svn tortoiseSvn cleanup 命令失败的解决办法
    svn add 命令 递归目录下所有文件
    m4出现Please port gnulib freadahead.c to your platform! Look at the definition of fflush, fread, ungetc on your system, then report this to bug-gnulib."
    Ubuntu下安装GCC,mpc、mpfr、gmp
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2654068.html
Copyright © 2011-2022 走看看