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);//實際建立一個對象??刹捎霉蚕韮却?/span>

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對象 ,直接壓入地址不行 ??稍趌api.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;
}

|