您的位置:首页 > 编程语言 > C语言/C++

关于squirrel语言与C++的自动绑定问题(2)

2016-03-20 20:29 471 查看
实现C++类自动绑定到Squirrel的核心类我是这样写的:

template<class T>struct SqModuleBase

{

    struct BaseT

    {

        T* pObject;

        bool flag_created;

        

    };

    

    static T* getHandle(HSQUIRRELVM v)

    {

        BaseT* handle;

        if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)(&handle),0))) return NULL;

        return handle->pObject;

    }

    static int _sq_get(HSQUIRRELVM v,const SQChar* &var,BaseT* &handle)

    {

        if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)(&handle),0)) || handle==NULL)

            return 0;//表示获取对象失败,立即返回

        if(SqGetVar(v,var))

        {

            if(strcmp(var,"this")==0)

            {

                sq_pushuserpointer(v,(SQUserPointer)handle->pObject);

                return 1; //表示处理get成功,立即返回

            }

            return -1; //表示继续后续的处理

        }

        return 0; //表示获取参数失败,立即返回

    }

template<class VAR2>

    static int _sq_get2(HSQUIRRELVM v,const SQChar* &var,BaseT* &handle)

    {

        VAR2 var2;

        if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)(&handle),0)) || handle==NULL)

            return 0;//表示获取对象失败,立即返回

        if(SqGetVar(v,var,var2))

        {

            return -1; //表示继续后续的处理

        }

        return 0; //表示获取参数失败,立即返回

    }

    static SQInteger _Sq2Constructor(HSQUIRRELVM v)

    {

        BaseT* handle=new BaseT;

        handle->pObject=NULL;

        handle->flag_created=false;

    

        sq_setinstanceup(v,1,(SQUserPointer)(handle));

        sq_setreleasehook(v,1,_queryobj_releasehook);

        return 0;

    }

    static SQInteger _queryobj_releasehook(SQUserPointer p, SQInteger size)

    {

        BaseT* handle=(BaseT*)p;

        if(handle!=NULL)

        {

            if(handle->flag_created) delete handle->pObject;

            delete handle;

        }

        return 0;

    }

    static SQInteger _Sq2_is_null(HSQUIRRELVM v)

    {

        BaseT* handle;

        if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)(&handle),0)))

        {

            sq_pushbool(v,SQTrue);

            return 1;

        }

        

        if(handle->pObject==NULL)

            sq_pushbool(v,SQTrue);

        else

            sq_pushbool(v,SQFalse);

        return 1;

    }

    static SQInteger _Sq2_Use(HSQUIRRELVM v)

    {

        BaseT* handle;

        if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)(&handle),0)))

            return 0;

        

        SQUserPointer p;

        if(SqGetVar(v,p) && p!=NULL)

        {

            if(handle->flag_created) delete handle->pObject;

            handle->pObject=(T*)p;

            handle->flag_created=false;

        }

        return 0;

    }

    static SQInteger _Sq2_ThisPtr(HSQUIRRELVM v)

    {

        BaseT* handle;

        if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)(&handle),0)))

            return 0;

        sq_pushuserpointer(v,(SQUserPointer)(handle->pObject));

        return 1;

    }

};

这是第一个类,我借鉴的是WTL的写法,这个类作为基础类实际上在C++内什么都没有存储,它的用处在后面体现

template<class T>struct SqModule:public SqModuleBase<T> //提供C++类的Squirrel封装

{

    typedef typename SqModuleBase<T>::BaseT ModuleType;

    

    static SQInteger Sq2_Create(HSQUIRRELVM v)

    {

        ModuleType* handle;

        if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)(&handle),0))

            || handle==NULL) return 0;

        if(handle->flag_created) delete handle->pObject;

        handle->pObject=new T;

        

        handle->flag_created=true;

        return 0;

    }

    static void inject_base_function(const SQChar* name,HSQUIRRELVM v)

    {

        int top=sq_gettop(v);

        sq_pushroottable(v);

        sq_pushstring(v,name,-1);

        sq_newclass(v,SQFalse);

        sq_createslot(v,-3);

        sq_settop(v,top);

        register_func(v,name,SqModuleBase<T>::_Sq2Constructor,"constructor","x");

        register_func(v,name,Sq2_Create,"create","x");

        register_func(v,name,SqModuleBase<T>::_Sq2_Use,"use","xp");

        register_func(v,name,SqModuleBase<T>::_Sq2_ThisPtr,"this_ptr","x");

        register_func(v,name,SqModuleBase<T>::_Sq2_ThisPtr,"this","x");

        register_func(v,name,SqModuleBase<T>::_Sq2_ThisPtr,"ptr","x");

        register_func(v,name,SqModuleBase<T>::_Sq2_is_null,"is_null","x");

    }

};

这是第二个类,同样,它在C++里也是什么都不存储,它继承了模板类SqModuleBase,这个关系有些绕来绕去的意思,但是通过这样的继承关系可以产生很多不同功能的SqModule类。

对于标准的C++类,我们以以下方式来定义一个新类

class Foo

{

privtae:

    int x;

pubicd:

    void set_x(int i){x=i;}

};

struct SqFoo:public SqModule<Foo>

{

};

SqFoo类包含了很多用于创建Squirrel对象的静态函数,它提供的create,this,use这几个基本的在squirrel中可以使用的方法
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: