1.其中lua脚本文件内容,t.lua如下:
function f(ab) print(ab) end
ret ,err= pcall(f, "hello world") print( ret) print(err) print("okkkkkkkkkkk")
2.代码如下:
#include "stdafx.h" #include <stdio.h> #include<iostream> //g++ -g lua_api-new.cpp -I/usr/local/include /usr/local/lib/liblua.a
using namespace std; extern "C" { #include <lua.h> #include <lauxlib.h> #include <lualib.h> } #define TRACE_TOP printf("top=%d\n",lua_gettop(L));
template <class T> class LuaMgr { public: static void Register(lua_State *L) { //构造函数 放到全局中(实际中建议集中放到单独表内)
lua_pushcfunction(L, &LuaMgr <T>::constructor); lua_setglobal(L, T::classname);
//建立元表
luaL_newmetatable(L, T::classname); //设置垃圾回收
lua_pushstring(L, "__gc"); lua_pushcfunction(L, &LuaMgr <T>::gc_obj); lua_rawset(L, -3);
//设置index
lua_pushstring(L, "__index"); lua_pushvalue(L, -2); lua_rawset(L, -3);
//设置类成员函数。 注意此部分的语法:function并没有直接声明在模板内
for (int i = 0; T::function[i].name; i++) { lua_pushstring(L, T::function[i].name); lua_pushnumber(L, i); //upvalue
lua_pushcclosure(L, &LuaMgr<T>::thunk, 1); lua_rawset(L, -3); //table["T::function[i].name"] = thunk;
}
}
static int constructor(lua_State *L)//构造函数返回表,该函数用于脚本调用
{ T* obj = new T(L);//实际建立一个对象。可采用共享内存
T** u = (T**)lua_newuserdata(L, sizeof(T*));//获得一个指针
*u = obj;
//设置u元表
luaL_getmetatable(L, T::classname); lua_setmetatable(L, -2);
return 1; //返回u
}
//该函数用于c层调用,创建对象。由于没有直接返回lua,而没有被引用,要防止被释放
static void* c_create(lua_State *L) { T* obj = new T(L);//实际建立一个对象。可采用共享内存
void** u = (void**)lua_newuserdata(L, sizeof(T*));//获得一个指针
*u = obj;
//设置u元表
luaL_getmetatable(L, T::classname); lua_setmetatable(L, -2); lua_pop(L,1); //最好存放在表内,防止在被释放,如放到全局lua_setglobal(L,"aaafff");
return u; //返回u
} static int thunk(lua_State *L) { int i = (int)lua_tonumber(L, lua_upvalueindex(1)); T** obj = static_cast <T**>(luaL_checkudata(L, 1, T::classname)); return ((*obj)->*(T::function[i].mfunc))(L);
}
static int gc_obj(lua_State *L) { T** obj = static_cast <T**>(luaL_checkudata(L, -1, T::classname)); delete (*obj); printf("deleteing\n"); return 0; }
struct RegType { const char *name; int(T::*mfunc)(lua_State*); };
};
class Base { public: Base() {} ~Base() {} int add(int a, int b) { return a + b; } };
class Foo //:public Base
{ public: Foo(lua_State *L) { printf("call Foo constructor\n"); } ~Foo() { printf("call Foo destructor\n"); }
int foo(lua_State *L) { printf("in foo function\n"); return 0; } int n_add(lua_State *L) { int a = NULL; int b = NULL; a = (int)luaL_checknumber(L, -2); b = (int)luaL_checknumber(L, -1); double result = a+b;//add(a, b);
lua_pushnumber(L, result); return 1; } /**//******************只需增加 ****************************************/ friend class LuaMgr <Foo>; private: static const LuaMgr <Foo>::RegType function[]; static const char classname[];
};
const char Foo::classname[] = "Foo"; const LuaMgr <Foo>::RegType Foo::function[] = { { "foo", &Foo::foo}, { "add_func", &Foo::n_add}, { NULL , NULL} }; /**//******************只需增加 end****************************************/
//驱动程序
int main() {
lua_State *L = lua_open(); luaopen_base(L);
LuaMgr <Foo>::Register(L);
luaL_dofile(L, "t.lua");
//直接在c 内建立userdata.可以把该user传给lua,在lua内操作对象。lua_newuserdata 地址和lua对象(TValue值)是不同的
//创建时候,必须保存lua对象 ,直接压入地址不行 。可在lapi.h 内增加接口 TValue * luaA_getobject (lua_State *L,int indx ) {return index2adr(L, indx);}
//void** u = (void** )LuaMgr <Foo>::c_create(L); //
lua_close(L); return 0; }
|