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;
}

|