extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
} #include <iostream>
#include <string>
using namespace std; int main()
{
//Lua示例代码
char *szLua_code =
"r = string.gsub(c_Str, c_Mode, c_Tag) --宿主给的变量 "
"u = string.upper(r)";
//Lua的字符串模式
char *szMode = "(%w+)%s*=%s*(%w+)";
//要处理的字符串
char *szStr = "key1 = value1 key2 = value2";
//目标字符串模式
char *szTag = "<%1>%2</%1>"; lua_State *L = luaL_newstate();
luaL_openlibs(L); //把一个数据送给Lua
lua_pushstring(L, szMode);
lua_setglobal(L, "c_Mode");
lua_pushstring(L, szTag);
lua_setglobal(L, "c_Tag");
lua_pushstring(L, szStr);
lua_setglobal(L, "c_Str"); //执行
bool err = luaL_loadbuffer(L, szLua_code, strlen(szLua_code),
"demo") || lua_pcall(L, , , );
if(err)
{
//如果错误,显示
cerr << lua_tostring(L, -);
//弹出栈顶的这个错误信息
lua_pop(L, );
}
else
{
//Lua执行后取得全局变量的值
lua_getglobal(L, "r");
cout << "r = " << lua_tostring(L,-) << endl;
lua_pop(L, ); lua_getglobal(L, "u");
cout << "u = " << lua_tostring(L,-) << endl;
lua_pop(L, );
}
lua_close(L);
return ;
}

这段代码把字符串中的key=value字符串全部转换成XML格式<key>value</key>
    在这个例子中,C++程序通过调用lua_pushstring把C字符串压入栈顶,lua_setglobal的作用是把栈顶的数据传到Lua环境中作为全局变量。
    执行代码完成后,使用lua_getglobal从Lua环境中取得全局变量压入栈顶,然后使用lua_tostring把栈顶的数据转成字符串。由于lua_tostring本身没有出栈功能,所以为了平衡(即调用前与调用后栈里的数据量不变),使用lua_pop弹出由lua_setglobal压入的数据。
    从上面的例子可以看出,C++和Lua之间一直围绕着栈在转,可见栈是极为重要的。有必要列出一些Lua C API中的主要栈操作先,它们的作用直接可以从函数名中看出。
压入元素到栈里

void lua_pushnil (lua_State *L);
void lua_pushboolean (lua_State *L, int bool);
void lua_pushnumber (lua_State *L, double n);
void lua_pushlstring (lua_State *L, const char *s, size_t length);
void lua_pushstring (lua_State *L, const char *s);
void lua_pushcfunction (lua_State *L, lua_CFunction fn);

查询栈里的元素

lua_isnil (lua_State *L, int index);
lua_isboolean (lua_State *L, int index);
int lua_isnumber (lua_State *L, int index);
int lua_isstring (lua_State *L, int index);
int lua_isfunction (lua_State *L, int index);
int lua_istable (lua_State *L, int index);
int lua_isuserdata (lua_State *L, int index);
lua_islightuserdata (lua_State *L, int index);
lua_isthread (lua_State *L, int index);

转换栈里的元素

int                lua_toboolean (lua_State *L, int index);
double lua_tonumber (lua_State *L, int index);
const char * lua_tostring (lua_State *L, int index);
const char * lua_tolstring (lua_State *L, int idx, size_t *len);
size_t lua_strlen (lua_State *L, int index);
lua_CFunction lua_tocfunction (lua_State *L, int idx);
void * lua_touserdata (lua_State *L, int idx);
lua_State * lua_tothread (lua_State *L, int idx);

Lua栈的维护

int  lua_gettop (lua_State *L);
取得栈顶元素的索引,即栈中元素的个数
void lua_settop (lua_State *L, int index);
设置栈顶索引,即设置栈中元素的个数,如果index<0,则从栈顶往下数,下同
void lua_pushvalue (lua_State *L, int index);
把栈中指定索引的元素复制一份到栈顶
void lua_remove (lua_State *L, int index);
删除指定索引的元素
void lua_insert (lua_State *L, int index);
移动栈顶元素到指定索引的位置,栈中数目没有改变
void lua_replace (lua_State *L, int index);
从栈顶弹出元素值并将其设置到指定索引位置,栈中的数目减一
int lua_checkstack (lua_State *L, int extra);
确保堆栈上至少有 extra 个空位。如果不能把堆栈扩展到相应的尺寸,函数返回 false 。这个函数永远不会缩小堆栈。
int lua_pop(L,n)
从栈顶弹出n个元素,它是一个lua_settop的包装:#define lua_pop(L,n) lua_settop(L, -(n)-1)

表的操作
上面的列表中并没有lua_pushtable和lua_totable,那么怎样取得或设置Lua中的table数据呢?
在Lua中,table是一个很重要的数据类型,在table中不仅可以象C中的数据一样放一组数据,还可以象map一样以key=value的方式存放数据,如Lua代码中的:

tb = {"abc",12,true,x=10,y=20,z=30}

前三个数据可以用tb[1]~tb[3]取得
    而后三个数据通过tb.x, tb.y, tb.z取得
尽管看起来很牛叉,不过剥开神奇的外衣,实际上Lua的table中,所有的数据都是以key=value的形式存放的,这句Lua代码也可以写成:

tb = {[1]="abc", [2]=12, [3] = true, ["x"]=10, ["y"]=20, ["z"]=30}

它的形式就是[key]=value,所谓的tb.x只是tb["x"]的语法糖而已,如果愿意,也可以用tb["x"]取得这个数据10。
我们把上面的例子改成使用表的

 ...
int main()
{
//Lua示例代码,使用table
char *szLua_code =
"x = {} --用于存放结果的table "
"x[1],x[2] = string.gsub(c.Str, c.Mode, c.Tag) --x[1]里是结果,x[2]里是替换次数 "
"x.u = string.upper(x[1])";
//Lua的字符串模式
char *szMode = "(%w+)%s*=%s*(%w+)";
//要处理的字符串
char *szStr = "key1 = value1 key2 = value2";
//目标字符串模式
char *szTag = "<%1>%2</%1>"; lua_State *L = luaL_newstate();
luaL_openlibs(L); //把一个tabele送给Lua
lua_newtable(L); //新建一个table并压入栈顶
lua_pushstring(L, "Mode");// key
lua_pushstring(L, szMode);// value
//设置newtable[Mode]=szMode
//由于上面两次压栈,现在table元素排在栈顶往下数第三的位置
lua_settable(L, -);
//lua_settable会自己弹出上面压入的key和value lua_pushstring(L, "Tag");// key
lua_pushstring(L, szTag);// value
lua_settable(L, -); //设置newtable[Tag]=szTag lua_pushstring(L, "Str");// key
lua_pushstring(L, szStr);// value
lua_settable(L, -); //设置newtable[Str]=szStr lua_setglobal(L,"c"); //将栈顶元素(newtable)置为Lua中的全局变量c //执行
bool err = luaL_loadbuffer(L, szLua_code, strlen(szLua_code),
"demo") || lua_pcall(L, , , );
if(err)
{
//如果错误,显示
cerr << lua_tostring(L, -);
//弹出栈顶的这个错误信息
lua_pop(L, );
}
else
{
//Lua执行后取得全局变量的值
lua_getglobal(L, "x"); //这个x应该是个table
if(lua_istable(L,-))
{
//取得x.u,即x["u"]
lua_pushstring(L,"u"); //key
//由于这次压栈,x处于栈顶第二位置
lua_gettable(L,-);
//lua_gettable会弹出上面压入的key,然后把对应的value压入
//取得数据,然后从栈中弹出这个value
cout << "x.u = " << lua_tostring(L,-) << endl;
lua_pop(L, ); //取得x[1]和x[2]
for(int i=; i<=; i++)
{
//除了key是数字外,与上面的没什么区别
lua_pushnumber(L,i);
lua_gettable(L,-);
cout << "x[" << i <<"] = " << lua_tostring(L,-) << endl;
lua_pop(L, );
}
} //弹出栈顶的x
lua_pop(L, );
}
lua_close(L);
return ;
}

本例中用到的新Lua C API是:

void lua_newtable (lua_State *L);
新建一个空的table并压入栈顶。
void lua_settable (lua_State *L, int idx);
lua_settable以table在栈中的索引作为参数,并将栈顶的key和value出栈,用这两个值修改table。
void lua_gettable (lua_State *L, int idx);
lua_gettable以table在栈中的索引作为参数,弹出栈顶的元素作为key,返回与key对应的value并压入栈顶。
最后,Lua告别针对table提供了存取函数
void lua_rawgeti (lua_State *L, int idx, int n)
取得table[n]并放到栈顶,上例中69-70行的lua_pushnumber(L,i);lua_gettable(L,-2);可以用lua_rawgeti(L,-1)代替。
lua_getfield (lua_State *L, int idx, const char *k)
取得table.k并放到栈顶,上例中57-59行的lua_pushstring(L,"u");lua_gettable(L,-2);可以替换成lua_getfield(L,-1,"u")。
void lua_setfield (lua_State *L, int idx, const char *k)
把栈顶的数据作为value放入table.k中,上例中的形如lua_pushstring(L, "key");lua_pushstring(L, value);lua_settable(L, -3);可以改成lua_pushstring(L, value);lua_setfield(L,-2,"key");的形式。
void lua_rawseti (lua_State *L, int idx, int n)
把栈顶的数据作为value放入table[n]中

转载:lua和c的交互的更多相关文章

  1. Lua基本语法-lua与C#的交互(相当简单详细的例子)

    lua脚本 与 C#的交互 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 1 Lua And C# -- ...

  2. Lua与C的交互

    Lua 与 C 的交互 Lua是一个嵌入式的语言,它不仅可以是一个独立运行的程序,也可以是一个用来嵌入其它应用的程序库. C API是一个C代码与Lua进行交互的函数集,它由以下几部分构成: 1.  ...

  3. cocos2d-x lua与c++简单交互

    cocos2d-x lua与c++简单交互 version: cocos2d-x 3.6 本文讲述lua与c++的一些简单交互: lua通过消息方式调用c++无参接口 c++调用lua带参接口 1.通 ...

  4. Lua与C/C++交互问题

    初学lua,遇到注册C/C++交互函数问题 在lua与C/C++交互时,C/C++的注册Lua函数若是一个有返回类型(压栈)而不是获取类型的时候应该返回1而不是返回0,否则会出现在Lua中值为nil( ...

  5. Lua与C++的交互

    这篇文章说的挺详细的:Lua与C++的交互

  6. lua与C/C++交互概要

    转 http://blog.csdn.net/wildfireli/article/details/22307635 Lua生来就是为了和C交互的,因此使用C扩展Lua或者将Lua嵌入到C当中都是非常 ...

  7. 通过lua栈了解lua与c的交互

    lua是如何执行的 其中分析.执行部分都是c语言实现的. lua与c的关系 lua的虚拟机是用c语言实现的,换句话说一段lua指令最终在执行时都是当作c语言来执行的,lua的global表,函数调用栈 ...

  8. Lua脚本和C++交互(一)

    现在,越来越多的C++服务器和客户端融入了脚本的支持,尤其在网游领域,脚本语言已经渗透到了方方面面,比如你可以在你的客户端增加一个脚本,这个脚本将会帮你在界面上显示新的数据,亦或帮你完成某些任务,亦或 ...

  9. lua和C++的交互(1)

    /* 以前听的一个故事,当年Java的创造者讲课的时候,一开始先拿一个简单的不能简单的小例子, 不断的扩展,最后成为一个复杂而完美的程序. 一个重要之重要的概念,就是栈.Lua与别的语言交互以及交换数 ...

  10. lua与c的交互(函数专用)

    Lua与C的交互 Lua是一个嵌入式的语言,它不仅可以是一个独立运行的程序,也可以是一个用来嵌入其它应用的程序库. C API是一个C代码与Lua进行交互的函数集,它由以下几部分构成: 1.  读写L ...

随机推荐

  1. 【Web应用-Web作业】Web 作业无法直接运行 jar 文件

    问题描述 在经典管理门户中将直接压缩的 jar 文件打包为 zip 包,上传到 web 作业时报错. 解决方法 jar 文件的运行需要依托于 java 进程,所以在运行 jar 文件时,我们都会以格式 ...

  2. 10个优秀的移动Web应用开发框架

    在最近几年里,移动互联网高速发展.市场潜力巨大.继计算机.互联网之后,移动互联网正掀起第三次信息技术革命的浪潮,新技术.新应用不断涌现.今天这篇文章向大家推荐10大优秀的移动Web开发框架,帮助开发者 ...

  3. Unity之脚本编译顺序

    根据官方的解释,它们的编译顺序如下: (1)所有在Standard Assets.Pro Standard Assets或者Plugins文件夹中的脚本会产生一个Assembly-CSharp-fil ...

  4. Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/dispatcher-servlet.xml]

    这是因为我把 [/WEB-INF/dispatcher-servlet.xml]的位置换成了[config/springmvc/dispatcher-servlet.xml] 因此idea在原来的位置 ...

  5. OpenCV2:介绍

    一.OpenCV简介 OpenCV所有的类和函数都在cv命名空间里面,可以用 using namespace cv; #include "opencv2/opencv.hpp" 1 ...

  6. pseudogene|鉴定功能基因|expressed se|quence tag

    基因 (鉴定DNA:可以直接利用DNA序列鉴别基因,但存在3个问题) 1.intron太长(使用用来连接的算法不可及) 2.因为通常功能基因的第一个oxen中有非编码区和启动子最后一个oxen中有终止 ...

  7. linux的less命令

    less 在查看之前不会加载整个文件.可以尝试使用 less 和 vi 打开一个很大的文件,你就会看到它们之间在速度上的区别. 在 less 中导航命令类似于 vi.本文中将介绍一些导航命令以及使用 ...

  8. java 操作mongodb查询条件的常用设置

    java操作mongodb进行查询,常用筛选条件的设置如下: 条件列表:BasicDBList condList = new BasicDBList(); 临时条件对象:BasicDBObject c ...

  9. 非memory空间有地址分配

    对于非memory空间有地址分配,是由于有寄存器配置,比如AHB.APB.一些外设.

  10. 【js】【ios】【safari】【兼容问题】【转发】JS IOS/iPhone的Safari不兼容Javascript中的Date()问题

    引用地址:http://www.cnblogs.com/yiven/p/6053872.html   1 var date = new Date('2016-11-11 11:11:11'); 2 d ...