|
|
下面讨论下怎么使用lua5.1实现面向对象的调用
以下为c++代码
// test_ua.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <vector>
extern "C"
{
#include "lua\lua.h"
#include "lua\lauxlib.h"
#include "lua\lualib.h"
}
#define LUA_STACK_SIZE 1024 // Lua Stack Size
lua_State * g_pLuaState; // Lua State
#define GetIntParam( Index ) \
\
( lua_Number ) lua_tonumber ( g_pLuaState, Index );
#define GetStrParam( Index ) \
\
( const char * ) lua_tostring ( g_pLuaState, Index );
#define REG_FUNCTION(name, f) \
lua_pushstring(g_pLuaState, name);\
lua_pushcfunction(g_pLuaState, f);\
lua_settable(g_pLuaState, -3)
#define DECLARE_INICLASS(name) name() \
{GetTableToLuaStack(g_pLuaState); \
AddToLua(g_pLuaState);\
lua_pop(g_pLuaState, 1); }
#define CallLuaFunc( FuncName, Params, Results, a ) \
{ \
lua_getglobal ( g_pLuaState, FuncName ); \
lua_pushnumber(g_pLuaState,a); \
lua_call ( g_pLuaState, Params, Results ); \
}
class LuaClassBase;
class TestLuaClassB;
class TestLuaClassA;
/*lua实现对象访问的基类*/
class LuaClassBase
{
public:
// void AddToLua(lua_State *L )
// {
//
// }
void GetTableToLuaStack(lua_State *L)/*把此实例对应的表获取到堆栈top处*/
{
lua_getfield(L, LUA_REGISTRYINDEX, "table_array");
lua_pushinteger(L, (int)this);
lua_gettable(L, -2);
lua_remove(L, -2);
}
LuaClassBase()/*把this作为key,实例对应的表作为value,添加到总表table_array中*/
{
lua_State *L = g_pLuaState;
lua_getfield(L, LUA_REGISTRYINDEX, "table_array");
lua_pushinteger(L, (int)this);
lua_newtable(L);
lua_pushlightuserdata(L, this);
lua_setfield(L, -2, "ObjectPtr");
lua_settable(L, -3);
lua_pop(L, 1);
/*
lua_getfield(L, LUA_REGISTRYINDEX, "table_array");
lua_pushinteger(L, (int)this);
lua_gettable(L, -2);
lua_remove(L, -2);
lua_pop(L, 1);
*/ }
~LuaClassBase()
{
lua_State *L = g_pLuaState;
lua_getfield(L, LUA_REGISTRYINDEX, "table_array");
lua_pushinteger(L, (int)this);
lua_pushvalue(L, -1);
lua_gettable(L, -3);
lua_pushlightuserdata(L, NULL);
lua_setfield(L, -2, "ObjectPtr");
lua_pop(L, 1);
lua_pushnil(L);
lua_settable(L, -3);
lua_pop(L, 1);
}
static LuaClassBase * GetParamClass(lua_State *L, int index)/*把表转化为实例指针*/
{
if (!lua_istable(L, index)) return NULL;
lua_pushstring(L, "ObjectPtr");
lua_gettable(L, index );/*根据key ObjectPtr,可以查找以实例指针为value的值*/
LuaClassBase *ptr = (LuaClassBase *)lua_touserdata(L, -1);
lua_pop(L, 1);
return ptr;
}
};
class TestLuaClassB:public LuaClassBase
{
public:
int a;
int b;
DECLARE_INICLASS(TestLuaClassB)
void IintData()
{
a=2;
b=2;
}
static void AddToLua(lua_State *L )
{
return ;
}
};
class TestLuaClassA:public LuaClassBase
{
public:
int a;
int b;
DECLARE_INICLASS(TestLuaClassA)
void IintData()
{
a=1;
b=1;
}
static void AddToLua(lua_State *L )
{
REG_FUNCTION("Add", Add);
return ;
}
static int Add(lua_State *L)
{
int n = lua_gettop(L); /* 参数的个数 */
TestLuaClassA *pThis=(TestLuaClassA *)LuaClassBase::GetParamClass(L,1);//第一个参数 转化为此实例指针
TestLuaClassB *ptrB=(TestLuaClassB *)LuaClassBase::GetParamClass(L,4); //第3个参数转化为TestLuaClassB实例指针
int a = lua_tonumber ( L, 2 );
int b= lua_tonumber ( L, 3 );
lua_pushnumber(L,a+b+pThis->a+pThis->b+ptrB->a+ptrB->b);//做完运算返回1个参数
return 1;
}
};
/******************************************************************************************
*
* InitLua ()
*
* Simple helper function for initializing a global Lua state and registering our host API
* with it.
*/
void InitLua ()
{
// Open a new Lua state
g_pLuaState = lua_open ( );
luaopen_base(g_pLuaState);
//luaL_openlibs(g_pLuaState);
//luaopen_io(g_pLuaState);
luaopen_string(g_pLuaState);
luaopen_math(g_pLuaState);
// Register our host API with Lua
lua_newtable(g_pLuaState);
lua_setfield(g_pLuaState, LUA_REGISTRYINDEX, "table_array");//设置主表(以后创建的;类将为此表里面的元素)
}
/******************************************************************************************
*
* ShutDownLua ()
*
* Shuts down Lua by closing the global state.
*/
void ShutDownLua ()
{
// Close Lua state
lua_close ( g_pLuaState );
}
int _tmain(int argc, _TCHAR* argv[])
{
InitLua ();
// Load our script
if ( luaL_dofile ( g_pLuaState, "./HelloWorld.lua" ) )
printf("err\n");
TestLuaClassA *testclassA=new TestLuaClassA();
testclassA->IintData();
TestLuaClassB *testclassB=new TestLuaClassB();
testclassB->IintData();
lua_getglobal ( g_pLuaState, "main" );
lua_getfield(g_pLuaState, LUA_REGISTRYINDEX, "table_array");
lua_pushinteger(g_pLuaState,(int)testclassA);//参数1
lua_gettable(g_pLuaState ,-2);
lua_pushinteger(g_pLuaState,(int)testclassB);//参数2
lua_gettable(g_pLuaState ,-3);
lua_remove(g_pLuaState, -3);
// Let the script initialize the rest
//lua_getglobal ( g_pLuaState, "main" );
lua_call (g_pLuaState, 2, 0 ); //调用lua里面的main函数,有两个参数
// Shut down Lua
// ShutDownLua ();
while(1);
return 0;
}
以下为lua代码
print(100);
function main(ab,cc)
local a=3;
local b=4;
print(1000)
local c=ab.Add(ab,a,b,cc)
print(c);
end
|
|