Last active
April 26, 2019 01:39
-
-
Save evilwk/c879258672851117a6377adf092dc84c to your computer and use it in GitHub Desktop.
Lua扩展函数 #Cpp #Lua
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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