Skip to content

Instantly share code, notes, and snippets.

@evilwk
Last active April 26, 2019 01:39
Show Gist options
  • Save evilwk/c879258672851117a6377adf092dc84c to your computer and use it in GitHub Desktop.
Save evilwk/c879258672851117a6377adf092dc84c to your computer and use it in GitHub Desktop.
Lua扩展函数 #Cpp #Lua
#pragma once
#define LUA_REGISTRYINDEX (10000)
#define LUA_ENVIRONINDEX (10001)
#define LUA_GLOBALSINDEX (10002)
#define lua_upvalueindex(i) (LUA_GLOBALSINDEX(i))
typedef struct lua_State lua_State;
typedef double lua_Number;
typedef int (*lua_CFunction) (lua_State *L);
typedef struct luaL_Reg
{
const char *name;
lua_CFunction func;
} luaL_Reg;
typedef lua_State *(*luaL_newstate_cdecl)(void);
typedef int (*luaL_newmetatable_cdecl)(lua_State *L, const char *tname);
typedef void *(*lua_newuserdata_cdecl)(lua_State *L, size_t size);
typedef void (*lua_rawset_cdecl)(lua_State *L, int index);
typedef void (*lua_setfield_cdecl)(lua_State *L, int index, const char *k);
typedef void (*lua_getfield_cdecl)(lua_State *L, int index, const char *k);
typedef void (*lua_gettable_cdecl)(lua_State *L, int index);
typedef int (*lua_setmetatable_cdecl)(lua_State *L, int index);
typedef lua_Number (*lua_tonumber_cdecl)(lua_State *L, int index);
typedef const char *(*luaL_checklstring_cdecl)(lua_State *L, int narg, size_t *l);
typedef void (*lua_pushcclosure_cdecl) (lua_State *L, lua_CFunction fn, int n);
typedef void (*lua_pushnumber_cdecl)(lua_State *L, lua_Number n);
typedef void (*lua_pushstring_cdecl)(lua_State *L, const char *s);
typedef void (*lua_pushboolean_cdecl)(lua_State *L, int b);
typedef void (*lua_pushvalue_cdecl)(lua_State *L, int index);
typedef void *(*luaL_checkudata_cdecl)(lua_State *L, int narg, const char *tname);
typedef int (*luaL_loadbuffer_cdecl)(lua_State *L, const char *buff, size_t sz, const char *name);
typedef struct LuaInterface
{
luaL_newstate_cdecl luaL_newstate_dll;
luaL_newmetatable_cdecl luaL_newmetatable_dll;
lua_newuserdata_cdecl lua_newuserdata_dll;
lua_setfield_cdecl lua_setfield_dll;
lua_rawset_cdecl lua_rawset_dll;
lua_getfield_cdecl lua_getfield_dll;
lua_setmetatable_cdecl lua_setmetatable_dll;
lua_gettable_cdecl lua_gettable_dll;
lua_pushcclosure_cdecl lua_pushcclosure_dll;
lua_pushnumber_cdecl lua_pushnumber_dll;
lua_pushstring_cdecl lua_pushstring_dll;
lua_pushboolean_cdecl lua_pushboolean_dll;
lua_pushvalue_cdecl lua_pushvalue_dll;
luaL_checkudata_cdecl luaL_checkudata_dll;
lua_tonumber_cdecl lua_tonumber_dll;
luaL_loadbuffer_cdecl luaL_loadbuffer_dll;
luaL_checklstring_cdecl luaL_checklstring_dll;
} LuaInterface;
template <class T> class LuaMgr
{
public:
static void Register(lua_State *L)
{
//构造函数
luaInterface.lua_pushcclosure_dll(L, &LuaMgr <T>::constructor, 0);
luaInterface.lua_setfield_dll(L, LUA_GLOBALSINDEX, T::classname);
//建立元表
luaInterface.luaL_newmetatable_dll(L, T::classname);
//设置垃圾回收
luaInterface.lua_pushstring_dll(L, "__gc");
luaInterface.lua_pushcclosure_dll(L, &LuaMgr <T>::gc_obj, 0);
luaInterface.lua_rawset_dll(L, 3);
//设置index
luaInterface.lua_pushstring_dll(L, "__index");
luaInterface.lua_pushvalue_dll(L, 2);
luaInterface.lua_rawset_dll(L, 3);
//设置类成员函数
for (int i = 0; T::function[i].name; i++)
{
luaInterface.lua_pushstring_dll(L, T::function[i].name);
luaInterface.lua_pushnumber_dll(L, i);
luaInterface.lua_pushcclosure_dll(L, &LuaMgr<T>::thunk, 1);
luaInterface.lua_rawset_dll(L, 3);
}
}
static int constructor(lua_State *L)
{
T *obj = new T(L);
T **u = (T **)luaInterface.lua_newuserdata_dll(L, sizeof(T *));
*u = obj;
luaInterface.lua_getfield_dll(L, LUA_REGISTRYINDEX, T::classname);
luaInterface.lua_setmetatable_dll(L, 2);
return 1;
}
static int thunk(lua_State *L)
{
int i = (int)luaInterface.lua_tonumber_dll(L, lua_upvalueindex(1));
T **obj = static_cast <T **>(luaInterface.luaL_checkudata_dll(L, 1, T::classname));
return ((*obj) > *(T::function[i].mfunc))(L);
}
static int gc_obj(lua_State *L)
{
T **obj = static_cast <T **>(luaInterface.luaL_checkudata_dll(L, 1, T::classname));
delete (*obj);
return 0;
}
struct RegType
{
const char *name;
int (T::*mfunc)(lua_State *);
};
private:
LuaMgr();
};
/*
class Foo
{
public:
Foo(lua_State *L)
{
}
int foo(lua_State *L)
{
return 0;
}
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},
{ NULL , NULL}
};
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment