文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>将c++注册到lua

将c++注册到lua

时间:2010-09-26  来源:wwm

今天看到一篇文章,介绍了c++到lua的注册,感觉不错。原文地址:http://topic.csdn.net/u/20080725/15/7b6a1be7-ad10-4410-abc2-3affcd81e8ff.html

#include <stdio.h>
extern "C"
{
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}
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 = add(a, b);
lua_pushnumber(L, result);
return 1;
}
static const char classname[];
static const luna <Foo>::RegType function[];

};

/////////利用lua wipper//luaWipper.h////////////
template <class T> class Luna {
  public:
    static void Register(lua_State *L) {
      lua_pushcfunction(L, &Luna <T>::constructor);
      //注册函数,在lua中创建function类型的值来表示Luna <T>::constructor
      //该函数并将类型为fucntion的值入栈
      lua_setglobal(L, T::className);
      //将上面的function值赋给全局变量T::className
      //在这里是将该值赋给下面的“Foo”:const char Foo::className[] = "Foo";
      luaL_newmetatable(L, T::className);
      //创建一个新表(将用作metatable),将新表放到栈顶并建立表和registry中类型名的联系。
      //这个关联是双向的:使用类型名作为表的key;
      //同时使用表作为类型名的key(这种双向的关联,使得其他的两个函数的实现效率更高)。
      lua_pushstring(L, "__gc");
      /*
      Lua以__gc元方法的方式提供了finalizers。这个元方法只对userdata类型的值有效。
      当一个userdatum将被收集的时候,并且usedatum有一个__gc域,
      Lua会调用这个域的值(应该是一个函数):以userdatum作为这个函数的参数调用。
      这个函数负责释放与userdatum相关的所有资源。
      */
      lua_pushcfunction(L, &Luna <T>::gc_obj);
      lua_settable(L, -3);

    }

    static int constructor(lua_State *L) {
      T* obj = new T(L);

      lua_newtable(L);

      lua_pushnumber(L, 0);
      T** a = (T**)lua_newuserdata(L, sizeof(T*));
      //void *lua_newuserdata (lua_State *L, size_t size);
   
      *a = obj;
      luaL_getmetatable(L, T::className);
      //void  luaL_getmetatable (lua_State *L, const char *tname);
      //函数获取registry中的tname对应的metatable。
      lua_setmetatable(L, -2);
      //lua_setmetatable函数将表(get到的)出栈,并将其设置为给定位置(上面userdatum)对象的metatable。
      lua_settable(L, -3); // table[0] = userdatum;即table[0] = obj

      for (int i = 0; T::Register[i].name; i++) {
        lua_pushstring(L, T::Register[i].name);
        lua_pushnumber(L, i);
        lua_pushcclosure(L, &Luna <T>::thunk, 1);

        lua_settable(L, -3);
        //table["T::Register[i].name"] = thunk;
      }
      return 1;
    }

    static int thunk(lua_State *L) {
      int i = (int)lua_tonumber(L, lua_upvalueindex(1));
      //当lua把C函数压入到堆栈里时会把参数存到updata里面,
      //获取第一个upvalue到当前值
      //函数lua_upvalueindex(实际是一个宏),用来产生一个upvalue 的假索引。
      //这个假索引除了不在栈中之外,和其他的索引一样。
      //表达式lua_upvalueindex(1)为第一个upvalue的索引。
      lua_pushnumber(L, 0);
      lua_gettable(L, 1);

      T** obj = static_cast <T**>(luaL_checkudata(L, -1, T::className));
      //luaL_checkudata检查在栈中指定位置的对象是否为带有给定名字的metatable的usertatum。
      //如果对象不存在正确的metatable,返回NULL(或者它不是一个userdata);
      //否则,返回userdata的地址。
      lua_remove(L, -1);
      return ((*obj)->*(T::Register[i].mfunc))(L);
      //&foo
    }

    static int gc_obj(lua_State *L) {
      T** obj = static_cast <T**>(luaL_checkudata(L, -1, T::className));
      delete (*obj);
      return 0;
    }

    struct RegType {
      const char *name;
      int(T::*mfunc)(lua_State*);
      //function pointer
    };
};
///////////////////////////////luawipper.h end//////////////////////////////

const char Foo::classname[] = "Foo";
const luna <Foo>::RegType Foo::function[] =
{
{ "foo", &Foo::foo},
{ "add", &Foo::n_add},
{ NULL , NULL    }
};

////////////////////test.lua////////////////
/*
local f = Foo()
f:foo()
print("add is:",f:add(5,6))
*/
////////////////////////////////////////////
//驱动程序
int main()
{
lua_State *L = lua_open();
luaopen_base(L);
luna <Foo>::Register(L);
luaL_dofile(L, "test.lua");
lua_close(L);
return 0;
}
相关阅读 更多 +
排行榜 更多 +
aha word

aha word

休闲益智 下载
精英狙击行动最新版

精英狙击行动最新版

飞行射击 下载
哆啦小镇中文版

哆啦小镇中文版

休闲益智 下载