• <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>
            隨筆 - 79  文章 - 58  trackbacks - 0
            <2007年6月>
            272829303112
            3456789
            10111213141516
            17181920212223
            24252627282930
            1234567

            常用鏈接

            留言簿(9)

            隨筆分類

            隨筆檔案

            文章檔案

            相冊(cè)

            搜索

            •  

            積分與排名

            • 積分 - 295412
            • 排名 - 87

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            pycxx是使用C++語(yǔ)言給python寫擴(kuò)展代碼的輔助庫(kù),他不像boost.python或者swig那樣封裝的很厚,

            只是對(duì)python API的簡(jiǎn)單封裝,將python的C API組織成類的形式。

            首先來(lái)看pycxx自帶模塊擴(kuò)展樣例:

            class example_module : public ExtensionModule<example_module>

            {

            public:

                example_module()

                : ExtensionModule<example_module>( "example" )

                {

                    add_varargs_method("sum", &example_module::ex_sum, 

            "sum(arglist) = sum of arguments");

                    add_varargs_method("test", &example_module::ex_test, 

            "test(arglist) runs a test suite");

                    initialize( "documentation for the example module" );

                }

                virtual ~example_module() {}

            private:

                Object ex_sum(const Tuple &a) { ... }

                Object ex_test(const Tuple &a) { ... }

            };

            創(chuàng)建擴(kuò)展模塊的步驟如下:

            1、從 template<class T> ExtensionModule模板類繼承,class T 實(shí)例為本類

            2、構(gòu)造函數(shù)傳入模塊名 ExtensionModule<example_module>( "example" )

            3、實(shí)現(xiàn)擴(kuò)展函數(shù),如實(shí)現(xiàn)了

               Object ex_sum(const Tuple &a) { ... }

            4、在構(gòu)造函數(shù)中加入擴(kuò)展函數(shù)

               add_varargs_method("sum", &example_module::ex_sum, 

            "sum(arglist) = sum of arguments");

            5、將擴(kuò)展模塊注冊(cè)到python中

               initialize( "documentation for the example module" );

            6、將模塊對(duì)象實(shí)例化,模塊屬于單一對(duì)象,給出的樣例是:

            void initexample()

            {

                static example_module* example = new example_module;

            }

             

            將擴(kuò)展模塊注冊(cè)到python中靠這個(gè)initialize函數(shù)

            void initialize( const char *module_doc="" )

            {

                //調(diào)用了基類的方法

                ExtensionModuleBase::initialize( module_doc );

                //....

            }

            //最終也就是調(diào)用了python的API注冊(cè)進(jìn)去了

            void ExtensionModuleBase::initialize( const char *module_doc )

            {

                PyObject *module_ptr = new ExtensionModuleBasePtr( this );

                Py_InitModule4

                (

                const_cast<char *>( m_module_name.c_str() ),    // name

                m_method_table.table(),                         // methods

                const_cast<char *>( module_doc ),               // docs

                module_ptr,                                     // pass to functions as "self"

                PYTHON_API_VERSION                              // API version

                );

            }

             

            可以看到注冊(cè)的時(shí)候傳入了m_method_table,是否這個(gè)加入擴(kuò)展函數(shù)的地方呢, 這里雖然可以加入,但實(shí)際上add_varargs_method

            是加入到method_map_t,相當(dāng)于該類的靜態(tài)成員中。

                    static void add_varargs_method( const char *name, method_varargs_function_t function, const char *doc="" )

                    {

                        method_map_t &mm = methods();

                        mm[ std::string( name ) ] = new MethodDefExt<T>( name, function, method_varargs_call_handler, doc );

                    }

            method_varargs_function_t是類的成員函數(shù)指針,原型如下,這也是pycxx用模板的主要原因了。

            typedef Object (T::*method_varargs_function_t)( const Tuple &args );

             

            在initialize函數(shù)里,遍歷了method_map_t,加入到模板的dict中。

                    void initialize( const char *module_doc="" )
                    {
                        ExtensionModuleBase::initialize( module_doc );
                        Dict dict( moduleDictionary() );

                        //
                        // put each of the methods into the modules dictionary
                        // so that we get called back at the function in T.
                        //
                        method_map_t &mm = methods();
                        EXPLICIT_TYPENAME method_map_t::const_iterator i = mm.begin();
                        EXPLICIT_TYPENAME method_map_t::const_iterator i_end = mm.end();
                        for ( ; i != i_end; ++i )
                        {
                            MethodDefExt<T> *method_def = (*i).second;

                            static PyObject *self = PyCObject_FromVoidPtr( this, do_not_dealloc );

                            Tuple args( 2 );
                            args[0] = Object( self );
                            args[1] = Object( PyCObject_FromVoidPtr( method_def, do_not_dealloc ) );

                            PyObject *func = PyCFunction_New
                                                (
                                                &method_def->ext_meth_def,
                                                new_reference_to( args )
                                                );

                            method_def->py_method = Object( func, true );

                            dict[ (*i).first ] = method_def->py_method;
                        }
                    }

             

            真正注冊(cè)到python中的函數(shù)其實(shí)是method_varargs_call_handler,即下面的method_def->ext_meth_def

                            Tuple args( 2 );
                            args[0] = Object( self );
                            args[1] = Object( PyCObject_FromVoidPtr( method_def, do_not_dealloc ) );

                            PyObject *func = PyCFunction_New
                                                (
                                                &method_def->ext_meth_def,
                                                new_reference_to( args )
                                                );

             

            method_varargs_call_handler函數(shù)實(shí)現(xiàn)如下,第一個(gè)參數(shù)_self_and_name_tuple就是上面的args,

            args[0]是this指針,args[1]保存著MethodDefExt,里面有成員指向所調(diào)用的函數(shù)

            extern "C" PyObject *method_varargs_call_handler( PyObject *_self_and_name_tuple, PyObject *_args )
            {
                try
                {
                    Tuple self_and_name_tuple( _self_and_name_tuple );

                    PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
                    void *self_as_void = PyCObject_AsVoidPtr( self_in_cobject );
                    if( self_as_void == NULL )
                        return NULL;

                    ExtensionModuleBase *self = static_cast<ExtensionModuleBase *>( self_as_void );
                    Tuple args( _args );

                    Object result
                            (
                            self->invoke_method_varargs
                                (
                                PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ),
                                args
                                )
                            );

                    return new_reference_to( result.ptr() );
                }
                catch( Exception & )
                {
                    return 0;
                }
            }

            上述實(shí)現(xiàn)里又調(diào)用invoke_method_varargs,實(shí)現(xiàn)如下,這里ext_varargs_function就是真正調(diào)用的函數(shù)了,如注冊(cè)的ex_sum

                    virtual Object invoke_method_varargs( void *method_def, const Tuple &args )
                    {
                        // cast up to the derived class, method_def and call
                        T *self = static_cast<T *>( this );
                        MethodDefExt<T> *meth_def = reinterpret_cast<MethodDefExt<T> *>( method_def );

                        return (self->*meth_def->ext_varargs_function)( args );
                    }

             

            posted on 2012-03-01 20:59 merlinfang 閱讀(2907) 評(píng)論(2)  編輯 收藏 引用 所屬分類: pycxx

            FeedBack:
            # re: pycxx 源碼分析-- 創(chuàng)建python擴(kuò)展模塊(1) 2012-03-01 23:48 dos命令大全
            表示對(duì)py一竅不通  回復(fù)  更多評(píng)論
              
            # re: pycxx 源碼分析-- 創(chuàng)建python擴(kuò)展模塊(1) 2012-03-02 09:00 tb
            分析得不錯(cuò)  回復(fù)  更多評(píng)論
              

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


            91久久成人免费| 精品综合久久久久久97| 久久综合九色综合网站| 日产久久强奸免费的看| 久久综合伊人77777麻豆| 亚洲精品99久久久久中文字幕| 久久国产精品二国产精品| 久久久99精品一区二区| 香蕉久久夜色精品国产小说| 国产精品久久久久久久久免费| 久久精品国产亚洲av水果派| 久久精品国产亚洲欧美| 国产精品午夜久久| 久久青青色综合| 久久精品午夜一区二区福利| 亚洲一本综合久久| 久久人人青草97香蕉| 久久久久久毛片免费播放| 久久精品国产半推半就| 四虎影视久久久免费| 久久亚洲欧美国产精品| 久久久久久综合一区中文字幕 | 亚洲日本va中文字幕久久| 无码国内精品久久人妻| 久久精品国产精品青草| 色欲综合久久躁天天躁| 99久久夜色精品国产网站| 91精品国产高清久久久久久io| 国产L精品国产亚洲区久久| 久久人与动人物a级毛片| 欧美综合天天夜夜久久| 久久久无码精品亚洲日韩京东传媒 | 久久精品一区二区三区AV| 国产精品久久久久影视不卡| 亚洲精品无码久久久| 国内精品久久久久久99蜜桃| 香蕉99久久国产综合精品宅男自 | 99久久99这里只有免费的精品| 久久黄视频| 狠色狠色狠狠色综合久久| 精品久久久久成人码免费动漫|