lua与c之间交互是通过“lua堆栈”通信的。不管是lua调用c还是c调用lua,都是通过操作lua堆栈实现的。顾名思义,lua堆栈也满足后进先出的特点,入栈/出栈都围绕栈顶进行的。与通用的栈不同的是,这个虚拟栈每个位置都对应一个索引,可以通过索引操作指定位置的数据。1代表栈底,向栈顶依次递增;-1代表栈顶,向栈底依次递减,如图。

1. lua中类型在c中如何表示

要实现c和lua之间的交互,先了解下lua中基本类型与c中类型怎么对应的。lua中有八种基本类型:nil、boolean、number、string、table、function、userdata、thread,其中,userdata分轻量用户数据(lightuserdata)和完成用户数据(userdata)两种。这些类型都可以压入栈中,在c中统一用TValue结构表示,是一个{值,类型}结构。

TValue->tt表示类型,类型定义在lua.h,nil为LUA_TNIL,boolean为LUA_TBOOLEAN等

// lua.h
#define LUA_TNIL                0
#define LUA_TBOOLEAN            1
#define LUA_TLIGHTUSERDATA      2
#define LUA_TNUMBER             3
#define LUA_TSTRING             4
#define LUA_TTABLE              5
#define LUA_TFUNCTION           6
#define LUA_TUSERDATA           7
#define LUA_TTHREAD             8

TValue->Value是个union:

int b:只存boolean类型,注:number类型并不存在这里,b只存boolean

lua_Number n:存放所有number类型

void *p:存放轻量用户数据类型(lightuserdata)

gcObject *gc:存放所有需要垃圾回收的类型,是一个指向union GCObject的指针,通过GCObject可以看到其包含string、userdata、closure、table、proto、upvalue、thread

由此可知,nil、boolean、number、lightuserdata类型是把数据本身直接存在栈里,和lua的垃圾回收无关;而GCObject表示的类型是把数据的内存地址(即指针)存在栈里的,当生命周期结束需要垃圾回收释放内存。

2. 对堆栈的基本操作

luaL_newstate:创建一个状态机,

lua_close:关闭状态机

#include <stdio.h>#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>int main(int argc, char *argv[]){lua_State *L = luaL_newstate(); //创建一个状态机lua_pushnil(L); //nilint type = lua_type(L, -1);printf("nil type = %d\n", type);if(lua_isnil(L, -1)){printf("------nil-----\n");}lua_pushboolean(L, 0); //booleantype = lua_type(L, -1);printf("boolean type = %d\n", type);if(lua_isboolean(L, -1))printf("--------boolean------\n");lua_pushlightuserdata(L, NULL); //lightuserdatatype = lua_type(L, -1);printf("lightuserdata type = %d\n", type);if(lua_islightuserdata(L, -1))printf("--------lightuserdata------\n");lua_pushnumber(L, 10); //numbertype = lua_type(L, -1);printf("number type = %d\n", type);if(lua_isnumber(L, -1))printf("--------number------\n");lua_pushstring(L, "string"); //stringtype = lua_type(L, -1);printf("string type = %d\n", type);if(lua_isstring(L, -1))printf("--------string------\n");lua_newtable(L); //table, 创建空表,并压入栈type = lua_type(L, -1);printf("table type = %d\n", type);if(lua_istable(L, -1))printf("--------table------\n");lua_newuserdata(L, 1024); //userdata, 分配1024大小的内存块,并把内存地址压入栈type = lua_type(L, -1);printf("userdata type = %d\n", type);if(lua_isuserdata(L, -1))printf("--------userdata------\n");lua_pushthread(L); //thread, 创建一个lua新线程,并将其压入栈。lua线程不是OS线程type = lua_type(L, -1);printf("thread type = %d\n", type);if(lua_isthread(L, -1))printf("--------thread------\n");lua_close(L); //关闭状态机return 0;
}

lua_pushXXX:push*族api向栈顶压入数据,比如lua_pushnumber压入数值,lua_pushstring压入字符串,lua_pushcclosure压入c闭包。

lua_isXXX:is*族api判断栈里指定位置的索引是否是指定类型,比如,lua_istable(L,-1)判断栈顶位置的数据是否是表,lua_isuserdata(L,-1)判断栈顶位置的数据是否是用户数据等。

gcc -o main.o main.c /usr/local/lib/liblua.a -I/usr/local/include/ -lm -ldl

运行结果如下,对应lua.h中的类型定义。c与lua之间详细的api介绍参照http://cloudwu.github.io/lua53doc/contents.html#contents

lua 和 c交互详解(一)相关推荐

  1. Unity-用户输入交互详解

    Unity-用户输入交互详解 1.简介 输入操作是游戏的基础操作之一. Unity支持的操作方式: 鼠标.键盘,小键盘(PC) 手柄(主机) 触屏操作.重力传感器.手势(移动平台) VR,AR 麦克风 ...

  2. redis lua 设置过期_详解 Redis 内存管理机制和实现

    Redis是一个基于内存的键值数据库,其内存管理是非常重要的.本文内存管理的内容包括:过期键的懒性删除和过期删除以及内存溢出控制策略. 最大内存限制 Redis使用 maxmemory 参数限制最大可 ...

  3. UVM基础-Seq-Sqr-Driver交互详解

    一.Sequence机制的使用方法 1.1 seq.sqr与driver 熟悉UVM的朋友都知道,在一个基于UVM搭建的验证环境中,Sequence负责产生环境所需的数据包:Transaction,而 ...

  4. lua java效率_luaJavaBridge详解

    cocos2d-x技术群新群:117871561 c++技术交流群:593010226 此文章献给 苦于接sdk的猿类(参考某技术人员的博客) 要实现java与lua的相互操作 传统做法是先用 C/C ...

  5. android fragment activity 交互,Android基础之Fragment与Activity交互详解

    今天继续讲解Fragment组件的特性,主要是跟Activity的交互和生命周期的关系,我们前面已经说过Fragment是依赖于Activity的,而且生命周期也跟Activity绑定一起.下面我们看 ...

  6. lua 函数调用1 -- 闭包详解和C调用

    这里, 简单的记录一下lua中闭包的知识和C闭包调用 前提知识: 在lua api小记2中已经分析了lua中值的结构, 是一个 TValue{value, tt}组合, 如果有疑问, 可以去看一下 一 ...

  7. Android WebView与JavaScript交互详解

    近期工作项目中遇到Android的WebView与js交互问题,之前也知道有这方面的技术可以实现.但在用的过程中,却发现还是需要用电心思. 现把我所了解的分享给大家,希望可以帮助到做类似项目的童鞋. ...

  8. [转]OC与JS的交互详解

    事情的起因还是因为项目需求驱动.折腾了两天,由于之前没有UIWebView与JS交互的经历,并且觉得这次在功能上有一定的创造性,特此留下一点文字,方便日后回顾. 我要实现这样一个需求:按照本地的CSS ...

  9. 小程序与后台 api接口数据交互详解(微信报修小程序源码讲解七)

    完成用户授权登录逻辑后,接下来的开发工作大部分都是与后台 api 接口的交互,本节我们详细讲解一下小程序如何与 api 进行交互 . 小程序如何发送 http/https 请求到后台? 小程序请求 h ...

最新文章

  1. 二阶声波正演c语言程序_嵌入式开发中的三种程序构架
  2. Actipro WPF Studio破解
  3. 麦克风阵列降噪_黄鹂智声降噪耳机E100u,与喧嚣说再见
  4. 算法导论之动态规划(最长公共子序列和最优二叉查找树)
  5. 二十个你必须知道的SEO概念
  6. Win10下如何更改默认浏览器
  7. JavaScript事件捕获与事件冒泡原理 IE和DOM之间存在哪些主要差别
  8. SSDB 配置文件详解
  9. 卡通自适应网址发布页源码
  10. GitHub for windows使用备忘录
  11. 【数学基础】深度学习必须掌握的 13 种概率分布
  12. C# 将数据导出到Excel汇总(转)
  13. sudo apt-get 与 yum
  14. 西门子1500和300哪个贵_西门子PLC S7-300和1500之间的通信资源管理之比较?
  15. De Casteljau算法
  16. Java常用类(三):FileUtils类
  17. Lambda-Stream应用
  18. 一般熟练盲打需要多久_练习拼音打字练到[盲打]的境界一般需要多久(时间)?...
  19. 一个普通前端的2022年终总结:多病的一年
  20. python背景怎么自定义铃声_iPhone —— 如何自制铃声(图文)

热门文章

  1. PyTorch:加载自己的数据集
  2. super和this关键字详解
  3. PhpStorm调用浏览器运行php文件
  4. 前端代码:html、css(图文混排)文字环绕 - 案例篇
  5. MUI 如何更改单选框样式
  6. 知识付费小程序源码支持流量主-瀑布流
  7. 一款漂亮的赞助打赏单页界面美化版源码
  8. python一行输出多个数据_Python高效数据分析的8个技巧
  9. easyui-super-theme后台模板
  10. 帐篷篷房建筑建材产品营销型网站源码 dedecms织梦模板