lua检测表中是否有某个值_Lua和C的互交互

本文介绍了如何在C中启动Lua,包括luaL_newstate和luaL_openLibs的使用。详细讲解了Lua的栈操作,如何从C调用Lua函数以及从Lua中调用C函数,并提供了示例。此外,还讨论了Lua中的注册表、上值和自定义类型,如full userdata和light userdata的应用。
摘要由CSDN通过智能技术生成

bed9c404e50d26b6e84ca38c0d3733b5.png

Lua在游戏中是非常常见的嵌入式语言,常用来做ui界面,ai逻辑脚本,手机热更等.最近一个项目中用到了lua,需要自己写一些lua的库.这块其实并不是很难,这里简单总结下.

建议对照lua的文档阅读 https://www.runoob.com/manual/lua53doc/contents.html, 里面有每个函数具体功能的解释.

以及lua的源码,lua.c就是C中调用lua的一个解释器实现,lmathlib.clstrlib.c就是lua的模块实现.

最后再推荐一本书,讲的非常详细:Programming in Lua, Fourth Edition.

从C中启动Lua

启动一个Lua State并处理输入:

#include <stdio.h>
#include <string.h>
#include "lua.h" //Lua头文件
#include "luaxlib.h" //Lua辅助库
#include "lualib.h" //Lua自带的库
int main(void) {
    
  char buff[256];
  int error;
  lua_State *L = luaL_newstate(); //初始化Lua State
  luaL_openlibs(L); //加载Lua自带的lib库
  while (fgets(buff, sizeof(buff), stdin) != NULL) {
    
    error = luaL_loadstring(L, buff) || lua_pcall(L, 0, 0, 0);
    if (error) {
    
      fprintf(stderr, "%sn", luaL_tostring(L, -1);
      lua_pop(L, 1);
    }
  }
  lua_close(L):
  return 0;
}

lua.h是Lua的主要头文件,包含了所有Lua提供的基础函数,里面的函数都是lua_开头.

luaxlib.h是Lua的辅助库头文件,里面的函数都是通过lua.h中提供的函数来实现的,是为了方便编程实现的一个辅助库,里面的函数都以luaL_开头.

luaL_newstate新建一个Lua State并返回一个指针,几乎所有的Lua交互函数都需要传入一个lua_State的指针作为第一个参数.

新建出来的Lua State是没有Lua的math,io等这些库甚至print函数的,luaL_openLibs是加载Lua自带的一些库.


栈的操作

Lua和C交互的最大特色就是使用一个虚拟的栈来实现,虚拟的栈上可以是任意类型的值,包括nil,number,string,userdata等.

Lua内部所有的值类型都是用TValue这种结构来实现的,TValue包括Value_tt,_tt标识Value的类型,Value是一个Union,可以表示不同类型的值,userdatestring*gc表示,lightuserdata*p表示.

/*
** Union of all Lua values
*/
typedef union Value {
    
  GCObject *gc;    /* collectable objects */
  void *p;         /* light userdata */
  int b;           /* booleans */
  lua_CFunction f; /* light C functions */
  lua_Integer i;   /* integer numbers */
  lua_Number n;    /* float numbers */
} Value;


#define TValuefields	Value value_; int tt_

typedef struct lua_TValue {
    
  TValuefields;
} TValue;

默认情况下栈满足LIFO.大部分函数需要通过索引index指定一个栈上元素的位置作为参数,索引的位置可以是正数或者负数,正数表示从栈底计数,负数表示从栈顶计数.比如一个有4个元素的栈的索引:

6ff72c299c388862af1392fa8e11e468.png

Push 元素:

void lua_pushnil         (Lua_State *L);
void lua_pushboolean     (Lua_State *L, int bool);
void lua_pushnumber      (Lua_State *L, lua_Number n);
void lua_pushinteger     (Lua_State *L, lua_Integr n);
void lua_pushlstring     (Lua_State *L, const char* s, size_t len);
void lua_pushstring      (Lua_State *L, const char* s);

检查栈上空余格子数:

int  lua_checkstack (lua_State *L, int n); //检查栈上空余的格子是否满足n个
void luaL_checkstack (lua_State *L, int sz, const char *msg); //检查栈上空余格子数,不满足则抛出一个异常信息

检查栈中元素类型:

int lua_isnumber (lua_State *L, int idx); //idx是索引位置
int lua_isstring (lua_State *L, int idx);
int lua_iscfunction (lua_State *L, int idx);
int lua_isinteger (lua_State *L, int idx);
int lua_isuserdata (lua_State *L, int idx);

int lua_type (lua_State *L, int idx);//将得到的值和LUA_TNIL,LUA_TNUMBER等比较来获取类型
const char* lua_typename(lua_State *L, int idx);//返回类型名称"nil","boolean","number"等

获取栈上的元素:

lua_Number lua_tonumber
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值