C++ 技术中心

   :: 首页 :: 联系 ::  :: 管理
  158 Posts :: 0 Stories :: 85 Comments :: 0 Trackbacks

公告

郑重声明:本BLOG所发表的原创文章,作者保留一切权利。必须经过作者本人同意后方可转载,并注名作者(天空)和出处(CppBlog.com)。作者Email:coder@luckcoder.com

留言簿(10)

搜索

  •  

最新随笔

最新评论

评论排行榜

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*));//获得一个指针

        
*= 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);//实际建立一个对象。可采用共享内存

        
void** u = (void**)lua_newuserdata(L, sizeof(T*));//获得一个指针

        
*= 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 
*= lua_open();
    luaopen_base(L);

    LuaMgr 
<Foo>::Register(L);

    luaL_dofile(L, 
"t.lua");

    
//直接在c 内建立userdata.可以把该user传给lua,在lua内操作对象。lua_newuserdata 地址和lua对象(TValue值)是不同的

    
//创建时候,必须保存lua对象 ,直接压入地址不行 。可在lapi.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;
}




posted on 2013-04-22 17:51 C++技术中心 阅读(2256) 评论(0)  编辑 收藏 引用 所属分类: C++ 基础

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理