• <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>

            馭風萬里無垠

            用Boost.Python + CMake + wxPython構建跨語言GUI程序<二>

            • Function

            接下來是函數(shù)部分,在根目錄下邊新添加一個子項目,連同其子目錄,并且在根目錄的CMakeLists.txt里邊加入對應聲明:

            mkdir Function;
            touch Function/CMakeLists.txt;
            touch Function/test.cpp
            對應的根目錄CMakeLists.txt后邊加入:
            add_subdirectory(Function)

            編輯Function的CMakeLists.txt:

            project(Function)
            set(lib_target function)
            
            include_directories(${Boost_INCLUDE_DIRS})
            add_library(${lib_target} SHARED test.cpp)
            set_target_properties(${lib_target} PROPERTIES PREFIX "")
            target_link_libraries(${lib_target} ${Boost_LIBRARIES})
            接下來就是實際的練習代碼,添于test.cpp里。

            1> 最常見的自由函數(shù),最基本的C函數(shù):

            //dummy function
            void dummyFunc()
            {
                cout << "Dummy function called!" << endl;
            }
            對應的Wrapper為:
            BOOST_PYTHON_MODULE(function)
            {
            def(fun, dummyFunc)
            ..................
            ..................
            }

            這里需要留意的是,對應的MODULE里邊的那個名字必須和CMakeLists.txt里邊制定的庫名字完全一樣,否則python導入對應的模塊時候會報錯誤。

            編譯之,只需要:

            cd ../Build;
            make
            ls lib/function.so
            cd lib
            在Python里邊測試,可以用了:
            $python
            Python 2.6.2 (r262:71600, Aug  8 2009, 19:23:16) 
            [GCC 4.4.1] on linux2
            Type "help", "copyright", "credits" or "license" for more information.
            >>> import function
            >>> function.dummyFunc()
            Dummy function called!
            >>> 

            2> 接下來是函數(shù)調(diào)用里邊,參數(shù)和返回值生存期的問題,因為有可能函數(shù)返回了一個內(nèi)部對象,必須要外部來釋放,或者返回對象指向參數(shù)對象的子對象,或者參數(shù)之間存在相互依賴等,這些都必須顯示指明,否則就可能被可惡的指針問題說羈絆。

            下邊是一個很極端的例子:

            ////////////////////////////////////////////////////////////////////////////////
            //calling policy
            struct InnerType
            {
                int i;
                int j;
            };
            
            struct RefType
            {
                float i;
                double j;
            };
            
            struct ComposedType
            {
                InnerType contained;
                RefType*  ref;
            };
            
            //really bad ?
            InnerType& Func(ComposedType& x, RefType* z)
            {
                x.ref = z;
                return x.contained;
            } 

            想正確的把最后這個Func導入到Python里邊用,就必須指明其參數(shù)之間的依賴關系以及返回值應用里邊的曲曲折折,就是z指向的對象必須又x來管理,而返回值則是x的一個子對象,這里用Policy來指定:

            class_<ComposedType>("ComposedType")
                    .def_readwrite("contained", &ComposedType::contained)
                    .def_readonly("ref", &ComposedType::ref);
                class_<RefType>("RefType")
                    .def_readwrite("i", &RefType::i)
                    .def_readwrite("j", &RefType::j);
                class_<InnerType>("InnerType")
                    .def_readwrite("i", &InnerType::i)
                    .def_readwrite("j", &InnerType::j);
            def("Func", Func,
                    return_internal_reference<1,
                    with_custodian_and_ward<1, 2> >()     
                );
            這種繁瑣的情況,還是盡量少用來做公有接口的好吧。
            一個測試的例子:
            Python 2.6.2 (r262:71600, Aug  8 2009, 19:23:16) 
            [GCC 4.4.1] on linux2
            Type "help", "copyright", "credits" or "license" for more information.
            >>> import function
            >>> x=function.ComposedType()
            >>> x.contained.i=1
            >>> x.contained.j=2
            >>> z=function.RefType()
            >>> z.i=1
            >>> z.j=3
            >>> y=function.Func(x,z)
            >>> y.i
            1
            >>> y.j
            2
            >>> y
            <function.InnerType object at 0x7fead87ff910>
            >>> 
            這里使用了類成員變量的導出來構造其他的輔助參數(shù)對象,例子也很直觀。后邊在Class的例子里邊還有更詳盡的闡釋。
            3> 函數(shù)重載
            重載是個很好的工具,可以用同樣的名字來描述不同的實現(xiàn),下邊的是一個成員函數(shù)重載的例子(其實和Free funciton的唯一差別就是聲明導出的時候,
            要在class_<T>對象的那個.后邊加def,而一般函數(shù)只要直接Def即可):
            ////////////////////////////////////////////////////////////////////////////////
            //Overloadding
            struct X
            { 
            
                bool f(int a)
                {
                    return true;
                } 
            
                bool f(int a, double b)
                {
                    return true;
                } 
            
                bool f(int a, double b, char c)
                {
                    return true;
                } 
            
                int f(int a, int b, int c)
                {
                    return a + b + c;
                };
            };

             

            聲明的時候,則要費時一點:

             //helpers
                bool    (X::*fx1)(int)              = &X::f;
                bool    (X::*fx2)(int, double)      = &X::f;
                bool    (X::*fx3)(int, double, char)= &X::f;
                int     (X::*fx4)(int, int, int)    = &X::f;
                class_<X>("X")
                    .def("f", fx1)
                    .def("f", fx2)
                    .def("f", fx3)
                    .def("f", fx4)
                    ;

            上邊用了幾個輔助函數(shù)來指向同一個函數(shù),然后將他們都導出到同一個python對象的同一個成員函數(shù)下邊即可。

            Python里邊調(diào)用的例子:

            >>> import function
            >>> obj=function.X()
            >>> help(obj.f)
            Help on method f:
            
            f(...) method of function.X instance
                f( (X)arg1, (int)arg2) -> bool :
                
                    C++ signature :
                        bool f(X {lvalue},int)
                
                f( (X)arg1, (int)arg2, (float)arg3) -> bool :
                
                    C++ signature :
                        bool f(X {lvalue},int,double)
                
                f( (X)arg1, (int)arg2, (float)arg3, (str)arg4) -> bool :
                
                    C++ signature :
                        bool f(X {lvalue},int,double,char)
                
                f( (X)arg1, (int)arg2, (int)arg3, (int)arg4) -> int :
                
                    C++ signature :
                        int f(X {lvalue},int,int,int)
            

            這里help給出的提示已經(jīng)包含了幾個重載的參數(shù),其中第一個參數(shù)就是C++的this指針或者python的self。

            >>> obj.f(1,1.1)
            True
            >>> obj.f(1,1, 3)
            5
            >>> function.X.f(obj, 1, 1.2, "msg")
            True

            上邊是兩種不同的參數(shù)調(diào)用X的重載成員函數(shù)版本。

            4> 函數(shù)參數(shù)的默認值

            這個是c++允許函數(shù)重載的另一種方式,簡單的方法是用一個簡單的wrapper來寫一些helper,如下:

            ////////////////////////////////////////////////////////////////////////////////
            //Default args
            int fn(int, double = 3.14, char const* = "hello")
            {
                return 1;
            }
            
            //wrapper
            int fn1(int x) {return fn(x);}
            int fn2(int x, double y) { return fn(x,y);}

            導出的方式和上邊類似:

                //default args
                def("f", fn);
                def("f", fn1);
                def("f", fn2);

            當然boost.python提供了一個宏來完成上邊的封裝,因此用下邊的方式則更簡單:

            BOOST_PYTHON_FUNCTION_OVERLOADS(fn_overloads, fn, 1, 3);
            
                def("fn", fn, fn_overloads());
            上邊的宏第一個參數(shù)指定了重載函數(shù)的名字,第二個是原來的函數(shù)名,最后兩個參數(shù)這表示最少和最多能夠接受多少個可變參數(shù)。

            調(diào)用示例:

            >>> func = function.f
            >>> help(func)
            Help on built-in function f:
            
            f(...)
                f( (int)arg1, (float)arg2, (str)arg3) -> int :
                
                    C++ signature :
                        int f(int,double,char const*)
                
                f( (int)arg1) -> int :
                
                    C++ signature :
                        int f(int)
                
                f( (int)arg1, (float)arg2) -> int :
                
                    C++ signature :
                        int f(int,double)
            >>> fn = function.fn
            >>> help(fn)
            Help on built-in function fn:
            
            fn(...)
                fn( (int)arg1 [, (float)arg2 [, (str)arg3]]) -> int :
                
                    C++ signature :
                        int fn(int [,double [,char const*]])
            >>> func(1,2.2, "str")
            1
            >>> fn(1)
            1
            >>> fn(1, 2.2)
            1

            5> 類的成員函數(shù)參數(shù)的默認值

            有些時候我們需要和類的成員函數(shù)打交道,所以對應的也有一個宏來完成那些繁雜的wrapper:

            ////////////////////////////////////////////////////////////////////////////////
            //Mem_fun
            struct Y
            {
                Y(int i, int j, int k=0, int p=1.2){}
                void mem_fn(int i, int j = 0, double k=1.2, const std::string& str="msg"){}
            }; 
            
            BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(mem_fn_overloads, mem_fn, 1, 4);

            宏的作用和上邊的那個用于普通函數(shù)的差不多。

            這里邊有一個構造函數(shù)默認值的問題,參考下邊的optional模板:

                //Mem_fn and optional init
                class_<Y>("Y", init<int, int, optional<int, double> >())
                    .def("mem_fn", &Y::mem_fn, mem_fn_overloads());

            posted on 2009-08-10 20:49 skyscribe 閱讀(631) 評論(0)  編輯 收藏 引用

            <2009年8月>
            2627282930311
            2345678
            9101112131415
            16171819202122
            23242526272829
            303112345

            導航

            統(tǒng)計

            常用鏈接

            留言簿(3)

            隨筆分類

            隨筆檔案

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            日韩亚洲国产综合久久久| 久久久无码人妻精品无码| 观看 国产综合久久久久鬼色 欧美 亚洲 一区二区 | 午夜不卡久久精品无码免费| 亚洲乱码日产精品a级毛片久久| 欧美日韩中文字幕久久伊人| 久久国产成人亚洲精品影院| 97久久国产综合精品女不卡| 久久夜色tv网站| 久久久久久久久久久| 国产成人精品综合久久久| 午夜精品久久久久久久久| 精品免费久久久久国产一区 | 久久青草国产精品一区| 国产A级毛片久久久精品毛片| 久久国产精品一区二区| 欧美熟妇另类久久久久久不卡| 久久精品国产福利国产琪琪| av无码久久久久久不卡网站| 久久亚洲精品成人无码网站| 国产精品九九久久免费视频 | 国产免费久久久久久无码| AV无码久久久久不卡蜜桃| 久久高清一级毛片| 午夜不卡888久久| 久久精品国产亚洲av水果派| 久久久久亚洲AV成人网人人网站| 久久精品无码免费不卡| 91精品国产91久久久久久青草| 国产精品一区二区久久| 久久综合给久久狠狠97色| 亚洲第一极品精品无码久久| 久久久无码精品亚洲日韩京东传媒| 久久久久综合国产欧美一区二区 | 久久精品亚洲男人的天堂| 狠狠色丁香久久综合婷婷| 久久精品成人国产午夜| 久久se精品一区精品二区| 国产精品久久自在自线观看| 91超碰碰碰碰久久久久久综合| 91久久精品国产成人久久|