• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 5, 文章 - 0, 評(píng)論 - 13, 引用 - 0
            數(shù)據(jù)加載中……

            luabind的converter和policy

                  現(xiàn)在的C++設(shè)計(jì),為了保證健壯性和復(fù)用性,特別是GP的流行,往往應(yīng)用了大量的模板,容器,智能指針。但這對(duì)與LUA綁定來說絕對(duì)不是一個(gè)好消息,非常的煩瑣。個(gè)人覺得,在第三方的綁定庫里面,luabind和現(xiàn)代C++設(shè)計(jì)結(jié)合最好,也是靈活性最高的一個(gè)綁定庫。
                  luabind確實(shí)很強(qiáng)大,但這里就不介紹一般應(yīng)用了,doc中有詳細(xì)的說明,使用也非常的簡單。我主要介紹一下converter和policy,特別是policy,簡直是luabind中的核武器,可以非常方便的讓容器,迭代子與lua相結(jié)合。但遺憾的是,luabind的文檔中并沒有對(duì)自定義convert和policy做一個(gè)詳細(xì)說明,那個(gè)converter的說明,牛頭不對(duì)馬嘴,sample中的any converter,更是無法編譯。
                  我這里通過容器vector的應(yīng)用來說明,怎么自定義convert和policy。
                  首先,我們來看這么一段代碼:
            void test1(const vector<string> &v) 

                copy(v.begin(),v.end(),ostream_iterator
            <string>(cout,"\n"));
            }
             

            vector
            <string> test2() 

                vector
            <string> r; 

                r.push_back(
            "r");
                r.push_back(
            "g");
                r.push_back(
            "b");

                
            return r; 
            }
             

            void main(){

                lua_State
            * L = lua_open();
                luaL_openlibs(L);

                open(L);

                module(L) 
                    [ 
                        def(
            "test1"&test1), 
                        def(
            "test2"&test2)
                    ]; 

                luaL_dostring(L,
            "test1({\"1\",\"2\",\"3\"}) vec=test2() for k, v in ipairs(vec) do print(k..\":\"..v) end");
                lua_close(L);
            }

                       毫無疑問,調(diào)用這段lua代碼,得不到任何正確的結(jié)果,甚至當(dāng)你把vector<string>當(dāng)參數(shù)傳給lua,會(huì)得到y(tǒng)ou are trying to use an unregistered type的一個(gè)assert。因?yàn)閘uabind并不知道怎樣去處理vector<string>這個(gè)東西。
               最簡單的做法,我們就是通過default_converter的特化,來實(shí)現(xiàn)容器的使用。luabind都是通過default_converter來把call_function的調(diào)用參數(shù)壓入lua調(diào)用棧,所有的default_converter特化都可以在policy.hpp中找到。比如,將std::string入棧的特化convert就是:
                  
            template <>
            struct default_converter<std::string>
              : native_converter_base
            <std::string>
            {
                
            static int compute_score(lua_State* L, int index)
                
            {
                    
            return lua_type(L, index) == LUA_TSTRING ? 0 : -1;
                }


                std::
            string from(lua_State* L, int index)
                
            {
                    
            return std::string(lua_tostring(L, index), lua_strlen(L, index));
                }


                
            void to(lua_State* L, std::string const& value)
                
            {
                    lua_pushlstring(L, value.data(), value.size());
                }

            }
            ;

               其中void to(lua_State* L, std::string const& value),是把string壓入棧中。而from是將一個(gè)棧中數(shù)據(jù)轉(zhuǎn)化為string,computer_score檢查棧中數(shù)據(jù)類型是否符合。很簡單,不是嗎?那讓我們來看看,我們的vector應(yīng)該怎么寫。
               

            namespace luabind
            {
                template 
            <class T>
                
            struct default_converter<vector<T> >
                    : native_converter_base
            <vector<T> >
                
            {
                    
            static int compute_score(lua_State* L, int index)
                    
            {
                        
            return (lua_type(L, index) == LUA_TTABLE )? 0 : -1;
                    }


                    vector
            <T>  from(lua_State* L, int index)
                    
            {
                        vector
            <T> container; 
                        luabind::
            object tbl(from_stack(L, index)); 
                        
                        
            for (luabind::iterator itr(tbl), end; itr != end; ++itr) 
                        

                            boost::optional
            <T> v = object_cast_nothrow<T>(*itr); 
                            
            if (v)
                                container.push_back(
            *v); 
                            }
             
                        }
             

                        
            return container; 
                    }


                    
            void to(lua_State* L, vector<T>  const& container)
                    
            {
                        lua_createtable(L, container.size(), 
            0); 

                        luabind::
            object tbl(from_stack(L, -1)); 
                        
            int n = 0

                        
            for (vector<T>::const_iterator itr = container.begin(); itr != container.end(); ++itr) 
                        

                            tbl[
            ++n] = *itr; 
                        }

                    }

                }
            ;

                template 
            <class T>
                
            struct default_converter<vector<T>  const&>
                    : default_converter
            <vector<T> >
                
            {};
            }

             

                 是不是很簡單啊。:) 再運(yùn)行上面那段代碼。。就得到了我們想要的正確結(jié)果:
               
               
                  至于luabind的policy,它就更強(qiáng)大了。我們來看看policy版本的容器,應(yīng)該怎么來做。luabind/contain_policy.hpp就實(shí)現(xiàn)了容器的使用。代碼如下

            // Copyright (c) 2003 Daniel Wallin and Arvid Norberg

            // Permission is hereby granted, free of charge, to any person obtaining a
            // copy of this software and associated documentation files (the "Software"),
            // to deal in the Software without restriction, including without limitation
            // the rights to use, copy, modify, merge, publish, distribute, sublicense,
            // and/or sell copies of the Software, and to permit persons to whom the
            // Software is furnished to do so, subject to the following conditions:

            // The above copyright notice and this permission notice shall be included
            // in all copies or substantial portions of the Software.

            // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
            // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
            // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
            // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
            // SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
            // ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
            // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
            // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
            // OR OTHER DEALINGS IN THE SOFTWARE.


            #ifndef LUABIND_CONTAINER_POLICY_HPP_INCLUDED
            #define LUABIND_CONTAINER_POLICY_HPP_INCLUDED

            #include 
            <luabind/config.hpp>
            #include 
            <luabind/detail/policy.hpp>
            #include 
            <boost/mpl/apply_wrap.hpp>

            namespace luabind namespace detail {

                
            namespace mpl = boost::mpl;

                template
            <class Policies>
                
            struct container_converter_lua_to_cpp
                
            {
                    template
            <class T>
                    T apply(lua_State
            * L, by_const_reference<T>int index)
                    
            {
                        typedef typename T::value_type value_type;

                        typedef typename find_conversion_policy
            <1, Policies>::type converter_policy;
                        typename mpl::apply_wrap2
            <converter_policy,value_type,lua_to_cpp>::type converter;

                        T container;

                        lua_pushnil(L);
                        
            while (lua_next(L, index))
                        
            {
                            container.push_back(converter.apply(L, LUABIND_DECORATE_TYPE(value_type), 
            -1));
                            lua_pop(L, 
            1); // pop value
                        }


                        
            return container;
                    }


                    template
            <class T>
                    T apply(lua_State
            * L, by_value<T>int index)
                    
            {
                        
            return apply(L, by_const_reference<T>(), index);
                    }


                    template
            <class T>
                    
            static int match(lua_State* L, by_const_reference<T>int index)
                    
            {
                        
            if (lua_istable(L, index)) return 0else return -1;
                    }


                    template
            <class T>
                    
            void converter_postcall(lua_State*, T, int{}
                }
            ;

                template
            <class Policies>
                
            struct container_converter_cpp_to_lua
                
            {
                    template
            <class T>
                    
            void apply(lua_State* L, const T& container)
                    
            {
                        typedef typename T::value_type value_type;

                        typedef typename find_conversion_policy
            <1, Policies>::type converter_policy;
                        typename mpl::apply_wrap2
            <converter_policy,value_type,lua_to_cpp>::type converter;

                        lua_newtable(L);

                        
            int index = 1;

                        
            for (typename T::const_iterator i = container.begin(); i != container.end(); ++i)
                        
            {
                            converter.apply(L, 
            *i);
                            lua_rawseti(L, 
            -2, index);
                            
            ++index;
                        }

                    }

                }
            ;

                template
            <int N, class Policies>
            //    struct container_policy : converter_policy_tag
                struct container_policy : conversion_policy<N>
                
            {
            //        BOOST_STATIC_CONSTANT(int, index = N);

                    
            static void precall(lua_State*const index_map&{}
                    
            static void postcall(lua_State*const index_map&{}

                    
            struct only_accepts_nonconst_pointers {};

                    template
            <class T, class Direction>
                    
            struct apply
                    
            {
                        typedef typename boost::mpl::if_
            <boost::is_same<lua_to_cpp, Direction>
                            , container_converter_lua_to_cpp
            <Policies>
                            , container_converter_cpp_to_lua
            <Policies>
                        
            >::type type;
                    }
            ;
                }
            ;

            }
            }


            namespace luabind
            {
                template
            <int N>
                detail::policy_cons
            <detail::container_policy<N, detail::null_type>, detail::null_type> 
                container(LUABIND_PLACEHOLDER_ARG(N)) 
                

                    
            return detail::policy_cons<detail::container_policy<N, detail::null_type>, detail::null_type>(); 
                }


                template
            <int N, class Policies>
                detail::policy_cons
            <detail::container_policy<N, Policies>, detail::null_type> 
                container(LUABIND_PLACEHOLDER_ARG(N), 
            const Policies&
                

                    
            return detail::policy_cons<detail::container_policy<N, Policies>, detail::null_type>(); 
                }

            }


            #endif // LUABIND_CONTAINER_POLICY_HPP_INCLUDED

               看一下,眼熟嗎,感覺怎樣?不過是container_converter_lua_to_cpp對(duì)應(yīng)著default_converter::from而container_converter_cpp_to_lua對(duì)應(yīng)著default_converter::to。
                  當(dāng)然,policy除了converter以為,還有關(guān)于對(duì)象生命周期的控制,具體的可以參加luabind目錄下的其他policy。


             

            posted on 2009-01-08 17:10 clane 閱讀(2710) 評(píng)論(2)  編輯 收藏 引用 所屬分類: LUAC++

            評(píng)論

            # re: luabind的converter和policy  回復(fù)  更多評(píng)論   

            高人!
            2009-02-14 15:47 | 金慶

            # re: luabind的converter和policy[未登錄]  回復(fù)  更多評(píng)論   

            那個(gè)any_converter稍作修改可以編譯過,增加幾個(gè)details::就行了。
            但是tmd:

            1,運(yùn)行起來不work,說Trying to use unregistered class
            2,這東西到底怎么工作的?那個(gè)convert_cpp_to_lua沒任何地方有關(guān)系阿
            2011-03-24 13:58 | alpha

            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            国产精品99久久久久久www| 久久人人爽人人爽人人AV东京热| 久久成人永久免费播放| 精品国产乱码久久久久软件| 狼狼综合久久久久综合网| 亚洲国产精品久久久久婷婷软件| 久久久久久久久久久久久久| 精品国产一区二区三区久久| 亚洲国产香蕉人人爽成AV片久久| 亚洲乱码中文字幕久久孕妇黑人| 91超碰碰碰碰久久久久久综合| 亚洲色欲久久久久综合网| 久久电影网2021| 亚洲精品午夜国产VA久久成人| 精品视频久久久久| 精品无码久久久久久午夜| 午夜福利91久久福利| 久久综合综合久久97色| 国产成人精品综合久久久| 久久久久亚洲精品中文字幕| 久久精品国产亚洲av影院| 久久亚洲AV无码精品色午夜| 精品无码久久久久久久动漫| 99久久精品毛片免费播放| 77777亚洲午夜久久多人| 久久强奷乱码老熟女网站| 91麻豆精品国产91久久久久久 | 久久综合色之久久综合| 狠狠色丁香婷综合久久| 久久精品国产亚洲AV麻豆网站 | 久久国产色AV免费看| 伊人久久精品影院| 人妻少妇精品久久| 思思久久好好热精品国产| 久久www免费人成看国产片| 国产69精品久久久久9999| 久久精品www| 伊人色综合久久天天| 国产精品99久久精品爆乳| 精品无码人妻久久久久久| 久久一区二区三区免费|