1.其中l(wèi)ua腳本文件內(nèi)容,t.lua如下:
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)
{
//構(gòu)造函數(shù) 放到全局中(實(shí)際中建議集中放到單獨(dú)表內(nèi))

lua_pushcfunction(L, &LuaMgr <T>::constructor);
lua_setglobal(L, T::classname);

//建立元表

luaL_newmetatable(L, T::classname);
//設(shè)置垃圾回收

lua_pushstring(L, "__gc");
lua_pushcfunction(L, &LuaMgr <T>::gc_obj);
lua_rawset(L, -3);

//設(shè)置index

lua_pushstring(L, "__index");
lua_pushvalue(L, -2);
lua_rawset(L, -3);

//設(shè)置類成員函數(shù)。 注意此部分的語法:function并沒有直接聲明在模板內(nèi)

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)//構(gòu)造函數(shù)返回表,該函數(shù)用于腳本調(diào)用

{
T* obj = new T(L);//實(shí)際建立一個(gè)對象??刹捎霉蚕韮?nèi)存

T** u = (T**)lua_newuserdata(L, sizeof(T*));//獲得一個(gè)指針

*u = obj;

//設(shè)置u元表

luaL_getmetatable(L, T::classname);
lua_setmetatable(L, -2);

return 1; //返回u

}

//該函數(shù)用于c層調(diào)用,創(chuàng)建對象。由于沒有直接返回lua,而沒有被引用,要防止被釋放

static void* c_create(lua_State *L)
{
T* obj = new T(L);//實(shí)際建立一個(gè)對象??刹捎霉蚕韮?nèi)存

void** u = (void**)lua_newuserdata(L, sizeof(T*));//獲得一個(gè)指針

*u = obj;

//設(shè)置u元表

luaL_getmetatable(L, T::classname);
lua_setmetatable(L, -2);
lua_pop(L,1);
//最好存放在表內(nèi),防止在被釋放,如放到全局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****************************************/



//驅(qū)動(dòng)程序

int main()
{

lua_State *L = lua_open();
luaopen_base(L);

LuaMgr <Foo>::Register(L);

luaL_dofile(L, "t.lua");

//直接在c 內(nèi)建立userdata.可以把該user傳給lua,在lua內(nèi)操作對象。lua_newuserdata 地址和lua對象(TValue值)是不同的

//創(chuàng)建時(shí)候,必須保存lua對象 ,直接壓入地址不行 ??稍趌api.h 內(nèi)增加接口 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;
}

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)
{
//構(gòu)造函數(shù) 放到全局中(實(shí)際中建議集中放到單獨(dú)表內(nèi))
lua_pushcfunction(L, &LuaMgr <T>::constructor);
lua_setglobal(L, T::classname);
//建立元表
luaL_newmetatable(L, T::classname);
//設(shè)置垃圾回收
lua_pushstring(L, "__gc");
lua_pushcfunction(L, &LuaMgr <T>::gc_obj);
lua_rawset(L, -3);
//設(shè)置index
lua_pushstring(L, "__index");
lua_pushvalue(L, -2);
lua_rawset(L, -3);
//設(shè)置類成員函數(shù)。 注意此部分的語法:function并沒有直接聲明在模板內(nèi)
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)//構(gòu)造函數(shù)返回表,該函數(shù)用于腳本調(diào)用
{
T* obj = new T(L);//實(shí)際建立一個(gè)對象??刹捎霉蚕韮?nèi)存
T** u = (T**)lua_newuserdata(L, sizeof(T*));//獲得一個(gè)指針
*u = obj;
//設(shè)置u元表
luaL_getmetatable(L, T::classname);
lua_setmetatable(L, -2);
return 1; //返回u
}
//該函數(shù)用于c層調(diào)用,創(chuàng)建對象。由于沒有直接返回lua,而沒有被引用,要防止被釋放
static void* c_create(lua_State *L)
{
T* obj = new T(L);//實(shí)際建立一個(gè)對象??刹捎霉蚕韮?nèi)存
void** u = (void**)lua_newuserdata(L, sizeof(T*));//獲得一個(gè)指針
*u = obj;
//設(shè)置u元表
luaL_getmetatable(L, T::classname);
lua_setmetatable(L, -2);
lua_pop(L,1);
//最好存放在表內(nèi),防止在被釋放,如放到全局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****************************************/


//驅(qū)動(dòng)程序
int main()
{
lua_State *L = lua_open();
luaopen_base(L);
LuaMgr <Foo>::Register(L);
luaL_dofile(L, "t.lua");
//直接在c 內(nèi)建立userdata.可以把該user傳給lua,在lua內(nèi)操作對象。lua_newuserdata 地址和lua對象(TValue值)是不同的
//創(chuàng)建時(shí)候,必須保存lua對象 ,直接壓入地址不行 ??稍趌api.h 內(nèi)增加接口 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;
}



