代码如下:
使用lua的string.gsub 函数转换字符串(作为例子):
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);
//把3个变量(c_Str, c_Mode, c_Tag)发送到Lua虚拟机
lua_pushstring(L, szMode);//把C字符串压入栈顶
lua_setglobal(L, "c_Mode");//lua_setglobal的作用是把栈顶的数据传到Lua环境中作为全局变量
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, 0, 0, 0);
if(err)
{
//如果错误,显示
cerr << lua_tostring(L, -1);
//弹出栈顶的这个错误信息
lua_pop(L, 1);
}
else
{
//Lua执行后取得全局变量的值
lua_getglobal(L, "r");//从Lua环境中取得全局变量压入栈顶
cout << "r = " << lua_tostring(L,-1) << endl;//把栈顶的数据转成字符串
lua_pop(L, 1);//调用前与调用后栈里的数据量不变
lua_getglobal(L, "u");
cout << "u = " << lua_tostring(L,-1) << endl;
lua_pop(L, 1);
}
lua_close(L);
return 0;
}
C++和Lua之间交互接口一直是依赖着栈。Lua C API就是用于操作栈的,操作列举如下:
1、虚拟机维护
lua_State *lua_newstate (lua_Alloc f, void *ud);创建的一个新的独立的状态机。如果创建不了(因为内存问题)返回 NULL 。参数 f 是一个分配器函数; Lua 将通过这个函数做状态机内所有的内存分配操作。第二个参数 ud ,这个指针将在每次调用分配器时被直接传入。
________________________________________
void lua_close (lua_State *L);
销毁指定 Lua 状态机中的所有对象(如果有垃圾收集相关的元方法的话,会调用它们),并且释放状态机中使用的所有动态内存。在一些平台上,你可以不必调用这个函数,因为当宿主程序结束的时候,所有的资源就自然被释放掉了。另一方面,长期运行的程序,比如一个后台程序或是一个 web 服务器,当不再需要它们的时候就应该释放掉相关状态机。这样可以避免状态机扩张的过大。
________________________________________
lua_Alloc lua_getallocf (lua_State *L, void **ud);
返回给定状态机的内存分配器函数。如果 ud 不是 NULL ,Lua 把调用 lua_newstate 时传入的那个指针放入 *ud 。
________________________________________
lua_setallocf
void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
把指定状态机的分配器函数换成带上指针 ud 的 f 。
2、存取lua全局变量
void lua_setglobal (lua_State *L, const char *name);作用是把栈顶的数据传到Lua环境中作为全局变量name
由一个宏定义出来:
#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, s)
void lua_getglobal (lua_State *L, const char *name);
把lua全局变量 name 里的值压入堆栈。 这个是用一个宏定义出来的:
#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, s)
3、压入元素到栈里
void lua_pushboolean (lua_State *L, int b);把 b 作为一个 boolean 值压入堆栈。
________________________________________
void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
把一个新的 C closure 压入堆栈。
当创建了一个 C 函数后,你可以给它关联一些值,这样就是在创建一个 C closure (参见 §3.4);接下来无论函数何时被调用,这些值都可以被这个函数访问到。为了将一些值关联到一个 C 函数上,首先这些值需要先被压入堆栈(如果有多个值,第一个先压)。接下来调用 lua_pushcclosure 来创建出 closure 并把这个 C 函数压到堆栈上。参数 n 告之函数有多少个值需要关联到函数上。 lua_pushcclosure 也会把这些值从栈上弹出。
________________________________________
void lua_pushcfunction (lua_State *L, lua_CFunction f);
将一个 C 函数压入堆栈。这个函数接收一个 C 函数指针,并将一个类型为 function 的 Lua 值压入堆栈。当这个栈定的值被调用时,将触发对应的 C 函数。
注册到 Lua 中的任何函数都必须遵循正确的协议来接收参数和返回值(参见 lua_CFunction)。
lua_pushcfunction 是作为一个宏定义出现的:
#define lua_pushcfunction(L,f) lua_pushcclosure(L,f,0)
________________________________________
const char *lua_pushfstring (lua_State *L, const char *fmt, ...);
把一个格式化过的字符串压入堆栈,然后返回这个字符串的指针。它和 C 函数 sprintf 比较像,不过有一些重要的区别:
* 摸你需要为结果分配空间:其结果是一个 Lua 字符串,由 Lua 来关心其内存分配(同时通过垃圾收集来释放内存)。
* 这个转换非常的受限。不支持 flag ,宽度,或是指定精度。它只支持下面这些: '%%' (插入一个 '%'), '%s' (插入一个带零终止符的字符串,没有长度限制), '%f' (插入一个 lua_Number), '%p' (插入一个指针或是一个十六进制数), '%d' (插入一个 int), '%c' (把一个 int 作为一个字符插入)。
________________________________________
void lua_pushinteger (lua_State *L, lua_Integer n);
把 n 作为一个整形数压栈。
________________________________________
void lua_pushlightuserdata (lua_State *L, void *p);
把一个 light userdata 压栈。
userdata 在 Lua 中表示一个 C 值。 light userdata 表示一个指针。它是一个像数字一样的值:你不需要专门创建它,它也没有独立的 metatable ,而且也不会被收集(因为从来不需要创建)。只要表示的 C 地址相同,两个 light userdata 就相等。
________________________________________
void lua_pushlstring (lua_State *L, const char *s, size_t len);
把指针 s 指向的长度为 len 的字符串压栈。 Lua 对这个字符串做一次内存拷贝(或是复用一个拷贝),因此 s 处的内存在函数返回后,可以释放掉或是重用于其它用途。字符串内可以保存有零字符。
________________________________________
void lua_pushnil (lua_State *L);
把一个 nil 压栈。
________________________________________
void lua_pushnumber (lua_State *L, lua_Number n);
把一个浮点数 n 压栈。
________________________________________
void lua_pushstring (lua_State *L, const char *s);
把指针 s 指向的以零结尾的字符串压栈。 Lua 对这个字符串做一次内存拷贝(或是复用一个拷贝),因此 s 处的内存在函数返回后,可以释放掉或是重用于其它用途。字符串中不能包含有零字符;第一个碰到的零字符会认为是字符串的结束。
________________________________________
int lua_pushthread (lua_State *L);
把 L 中提供的线程压栈。如果这个线程是当前状态机的主线程的话,返回 1 。
________________________________________
void lua_pushvalue (lua_State *L, int index);
把堆栈上给定有效处索引处的元素作一个拷贝压栈。
________________________________________
const char *lua_pushvfstring (lua_State *L,
const char *fmt,
va_list argp);
等价于 lua_pushfstring,不过是用 va_list 接收参数,而不是用可变数量的实际参数。
________________________________________
void *lua_newuserdata (lua_State *L, size_t size)
创建C值到栈
返回值是新分配的块的地址
栈+1, 栈顶是userdata
userdata用来在lua中表示c中的值. 一个完整的userdata有自己的元表, 在垃圾回收时, 可以调用它的元表的__gc方法
________________________________________
void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n)
向栈上压一个C闭包
当一个c函数被创建时, 可以绑定几个值在它上面, 从而形成一个闭包. 在任何时刻调用这个c函数时, 都可以访问这几个绑定值.
绑定的方法: 先一次压入要绑定的n个值到栈上, 然后调用lua_pushcclosure(L, fn, n)这样就形成的一个c闭包
无返回值
栈 –(n - 1) , 一共弹出n个元素(及那些绑定的值), 压入一个cclosure
#define lua_pushcfunction(L, f) lua_pushcclosure(L, f, 0)
#define lua_register(L, n, f) (lua_pushcfunction(L, f), lua_setglobal(L, n))
没有返回值
栈不变化
这个是比较常用的, 以n为lua中的key压入一个0个绑定值的cclosure.
________________________________________
int lua_load (lua_State *L,
lua_Reader reader,
void *data,
const char *chunkname);
加载一个 Lua chunk 。如果没有错误, lua_load 把一个编译好的 chunk 作为一个 Lua 函数压入堆栈。否则,压入出错信息。 lua_load 的返回值可以是: