青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆 - 79  文章 - 58  trackbacks - 0
<2008年4月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

常用鏈接

留言簿(9)

隨筆分類

隨筆檔案

文章檔案

相冊

搜索

  •  

積分與排名

  • 積分 - 297342
  • 排名 - 89

最新評論

閱讀排行榜

評論排行榜

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

只是對python API的簡單封裝,將python的C API組織成類的形式。

首先來看pycxx自帶模塊擴展樣例:

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) { ... }

};

創建擴展模塊的步驟如下:

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

2、構造函數傳入模塊名 ExtensionModule<example_module>( "example" )

3、實現擴展函數,如實現了

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

4、在構造函數中加入擴展函數

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

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

5、將擴展模塊注冊到python中

   initialize( "documentation for the example module" );

6、將模塊對象實例化,模塊屬于單一對象,給出的樣例是:

void initexample()

{

    static example_module* example = new example_module;

}

 

將擴展模塊注冊到python中靠這個initialize函數

void initialize( const char *module_doc="" )

{

    //調用了基類的方法

    ExtensionModuleBase::initialize( module_doc );

    //....

}

//最終也就是調用了python的API注冊進去了

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

    );

}

 

可以看到注冊的時候傳入了m_method_table,是否這個加入擴展函數的地方呢, 這里雖然可以加入,但實際上add_varargs_method

是加入到method_map_t,相當于該類的靜態成員中。

        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是類的成員函數指針,原型如下,這也是pycxx用模板的主要原因了。

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

 

在initialize函數里,遍歷了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;
            }
        }

 

真正注冊到python中的函數其實是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函數實現如下,第一個參數_self_and_name_tuple就是上面的args,

args[0]是this指針,args[1]保存著MethodDefExt,里面有成員指向所調用的函數

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;
    }
}

上述實現里又調用invoke_method_varargs,實現如下,這里ext_varargs_function就是真正調用的函數了,如注冊的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 閱讀(2961) 評論(2)  編輯 收藏 引用 所屬分類: pycxx

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

只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
              午夜激情一区| 美女性感视频久久久| 欧美日韩国产美| 夜夜夜精品看看| 一区二区三区精品久久久| 欧美另类久久久品| 亚洲网站在线播放| 亚洲欧美日韩精品久久奇米色影视| 国产精品主播| 久久久噜噜噜久久中文字幕色伊伊| 久久久精品视频成人| 91久久精品国产91久久性色| 日韩亚洲欧美一区| 国产精品一卡二卡| 欧美va亚洲va国产综合| 欧美激情中文字幕乱码免费| 亚洲一区免费网站| 久久精品免费播放| 99视频精品| 性欧美办公室18xxxxhd| 亚洲人成亚洲人成在线观看图片| 亚洲乱码日产精品bd| 国产亚洲精品久久久久久| 欧美成人免费一级人片100| 欧美日韩中文字幕综合视频| 久久久久国产一区二区三区四区| 美女被久久久| 久久av老司机精品网站导航 | 亚洲天堂男人| 久久久精品国产免大香伊| 一本久道久久综合中文字幕 | 欧美激情一区二区三区| 国产精品夫妻自拍| 奶水喷射视频一区| 国产精品日韩在线播放| 欧美激情一二三区| 国模精品一区二区三区色天香| 亚洲欧洲一区二区三区在线观看 | 久久综合久久综合久久综合| 亚洲一区二区三区免费观看 | 午夜精彩国产免费不卡不顿大片| 欧美一二区视频| 亚洲精品乱码久久久久久蜜桃麻豆| 亚洲欧美成人| 夜夜嗨av一区二区三区网页| 久久久国产视频91| 欧美中文字幕在线观看| 欧美日韩中文字幕综合视频 | 99精品欧美一区二区三区综合在线| 亚洲欧美日韩在线观看a三区| 亚洲精品日韩在线观看| 久久国产天堂福利天堂| 欧美一区视频在线| 国产精品日韩在线播放| 艳女tv在线观看国产一区| 日韩午夜剧场| 欧美激情一区二区三级高清视频| 欧美jjzz| 亚洲精品小视频在线观看| 噜噜噜91成人网| 欧美福利在线| 亚洲精品日产精品乱码不卡| 美女成人午夜| 亚洲成色777777女色窝| 亚洲国产高清一区| 久久一区二区三区四区| 欧美刺激性大交免费视频| 在线观看日韩www视频免费| 久久久久久精| 免费一级欧美片在线观看| 亚洲国产精品久久| 欧美1区视频| 亚洲精品裸体| 亚洲在线视频免费观看| 国产精品卡一卡二| 亚洲欧美日韩在线播放| 久久久久久网址| 尤物精品国产第一福利三区| 老司机aⅴ在线精品导航| 欧美激情视频网站| 中文国产亚洲喷潮| 国产精品在线看| 久久精品女人| 亚洲日本中文字幕| 欧美在线看片a免费观看| 国产专区欧美精品| 欧美11—12娇小xxxx| 一区二区三区国产在线观看| 欧美一进一出视频| 亚洲国产高清aⅴ视频| 欧美日韩视频第一区| 亚洲午夜一区| 欧美a级在线| 亚洲欧美第一页| 韩国精品久久久999| 欧美成人激情视频| 亚洲欧美日本日韩| 欧美a级片网| 亚洲免费影视第一页| 在线看成人片| 欧美性生交xxxxx久久久| 久久久福利视频| 在线亚洲成人| 欧美国产一区二区在线观看| 午夜在线观看欧美| 亚洲精品看片| 国产一区二区三区在线免费观看 | 欧美色区777第一页| 欧美在线看片| 一区二区精品在线| 欧美国产欧美亚洲国产日韩mv天天看完整 | 亚洲欧美日韩国产综合在线| 欧美国产综合视频| 久久精品国产精品亚洲综合| 99视频精品免费观看| 黄色成人免费观看| 国产欧美精品一区二区色综合 | 欧美福利精品| 久久av一区二区三区漫画| 一区二区三区高清不卡| 亚洲国产精品v| 蜜臀久久久99精品久久久久久 | 亚洲精品一区二区网址| 国产目拍亚洲精品99久久精品 | 美女主播视频一区| 欧美一区免费| 亚洲欧美精品在线| 国产精品99久久久久久久vr| 亚洲国产精品小视频| 免费人成精品欧美精品| 久久久国产精品亚洲一区 | 亚洲精品激情| 在线看不卡av| 在线播放日韩| 一区二区视频在线观看| 国产午夜精品美女毛片视频| 国产精品你懂的在线欣赏| 欧美日韩在线播放三区| 欧美日韩第一区| 欧美日韩亚洲视频| 欧美日韩一区在线| 欧美日韩一区在线观看| 欧美日韩在线影院| 欧美午夜激情视频| 国产精品vvv| 欧美日韩综合精品| 国产精品欧美一区二区三区奶水| 欧美日韩在线一二三| 国产精品久久久99| 国产精品视频一二三| 国产日韩1区| 好看的日韩视频| 亚洲国产精品va在看黑人| 亚洲人屁股眼子交8| 一本色道久久88亚洲综合88| 亚洲一区中文| 久久久久久久久岛国免费| 久久一区激情| 亚洲欧洲一区二区三区久久| 夜夜嗨av一区二区三区免费区| 一区二区冒白浆视频| 亚洲欧美日韩人成在线播放| 久久久久久黄| 欧美精品国产精品| 国产精品自拍一区| 亚洲电影在线| 夜夜夜久久久| 久久九九国产精品| 亚洲精华国产欧美| 亚洲在线视频观看| 玖玖玖免费嫩草在线影院一区| 欧美国产日本在线| 国产精品你懂的| 在线精品福利| 亚洲欧美日韩精品久久久久| 久久午夜激情| 日韩亚洲在线| 久久久久久久网站| 欧美区视频在线观看| 国产日韩在线视频| 99精品国产在热久久| 久久久91精品国产一区二区精品| 亚洲第一精品夜夜躁人人爽 | 日韩亚洲欧美一区| 久久精品国产精品亚洲综合| 欧美精品日韩| 影音国产精品| 亚洲欧美一区二区三区久久| 欧美福利视频| 久久成人综合视频| 国产精品黄色在线观看| 亚洲国产精品va在线看黑人| 午夜精彩视频在线观看不卡| 亚洲激情影视| 久久全球大尺度高清视频| 国产精品麻豆成人av电影艾秋| 亚洲黄色免费| 欧美成年人网| 欧美在线观看网站| 国产欧美一区二区视频|