zoukankan      html  css  js  c++  java
  • 用C C++ 编写lua模块的一般模式

    作为一种嵌入式语言,lua提供了一套完备的 C API来帮助 lua 与 宿主程序进行交互。因此使用 C 或者 C++ 来为lua编写模块是很容易的。

    看一下lua (5.1) 中对 string 模块的封装源码 lstrlib.c

    在 lstrlib.c 最后有这样的代码

    
    /**
        将函数名与实际调用函数记录在一个 struct 中,并组成一个数组
        --- 有点 lua 代码的赶脚 ---
    **/
    static const luaL_Reg strlib[] = {
      {"byte", str_byte},
      {"char", str_char},
      {"dump", str_dump},
      {"find", str_find},
      {"format", str_format},
      {"gmatch", gmatch},
      {"gsub", str_gsub},
      {"len", str_len},
      {"lower", str_lower},
      {"match", str_match},
      {"rep", str_rep},
      {"reverse", str_reverse},
      {"sub", str_sub},
      {"upper", str_upper},
      {"pack", str_pack},
      {"packsize", str_packsize},
      {"unpack", str_unpack},
      {NULL, NULL}
    };
    
    /**
        这里是对创建的lib 元表进行后续加工,具体可以看源代码
    **/
    static void createmetatable (lua_State *L) {
        ....
    }
    
    
    /*
    ** Open string library
    ** 这里是string 库的主入口
    */
    LUAMOD_API int luaopen_string (lua_State *L) {
      luaL_newlib(L, strlib); // 创建一个 lib 元表,并将 strlib 5.2之前使用luaL_register(L, "modulename", modulename); 中的函数名与函数放到表中
      createmetatable(L); // 对创建的 lib 元表进行再次处理
      return 1;
    }
    

    类似的代码也出现再了 loadlib.c(package模块)、loslib.c(os 模块)

    因此可以总结出 lua 模块的编写方式

    • 1、定义 C/C++ 中的 函数
    • 2、定义 luaL_Reg 数组
    • 3、创建 lib 元表。这里需要注意 在 5.2 之后的版本中可以直接使用 luaL_newlib,而之前的版本需要使用 luaL_register(L, "modulename", modulename);

    C/C++ 与 lua 类型

    将数据传入lua接口

    /**
        向栈中压入 NULL
    **/
    LUA_API void  (lua_pushnil) (lua_State *L);
    
    /**
        向栈中压入 double
    **/
    LUA_API void  (lua_pushnumber) (lua_State *L, lua_Number n);
    
    /**
        向栈
    **/
    LUA_API void  (lua_pushinteger) (lua_State *L, lua_Integer n);
    
    /**
        将字符串s的指定长度len压入栈中
    **/
    LUA_API void  (lua_pushlstring) (lua_State *L, const char *s, size_t l);
    
    /**
        向栈中压入一个字符串
    **/
    LUA_API void  (lua_pushstring) (lua_State *L, const char *s);
    
    /**
        向栈中压入字符串并格式化
    **/
    LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
                                                          va_list argp);
    /**
        向栈中压入字符串并格式化
        使用可变参数进行格式化
    **/
    LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
    
    /**
        向栈中压入一个C函数
    **/
    LUA_API void  (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
    
    /**
        将 b 作为布尔值压入栈中
    **/
    LUA_API void  (lua_pushboolean) (lua_State *L, int b);
    
    /**
        将一个轻量用户数据压入栈中
    **/
    LUA_API void  (lua_pushlightuserdata) (lua_State *L, void *p);
    
    /**
      "L"表示的线程入栈。如果这个线程是当前状态机的主线程的话,返回1。
    **/
    LUA_API int   (lua_pushthread) (lua_State *L);
    
  • 相关阅读:
    多元化时代敏捷软件开发的崛起与传统软件工程的延续
    敏捷软件开发与传统软件工程概述比较
    结构化方法和面向对象方法的比较
    sql server 的Maintenance Plans(维护计划)详解
    sql server 如何查询出数据库作业所有者的信息并完成批量替换
    sql server 运维时CPU,内存,操作系统等信息查询(用sql语句)
    sql server 数据导出(入)方法总结
    sql server 转置 和实现随机分配和一串代码的含义拼在一行
    python 之路初(一):pycharm 安装 和 环境配置 和 中文乱码问题
    Qt5.9.6 vs2015 SQlite 数据库增删改查
  • 原文地址:https://www.cnblogs.com/pmsl/p/8527593.html
Copyright © 2011-2022 走看看