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

隨筆 - 79  文章 - 58  trackbacks - 0
<2012年5月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

常用鏈接

留言簿(9)

隨筆分類

隨筆檔案

文章檔案

相冊

搜索

  •  

積分與排名

  • 積分 - 297020
  • 排名 - 88

最新評論

閱讀排行榜

評論排行榜

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 閱讀(2953) 評論(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>
              久久久一本精品99久久精品66| 欧美一区二区高清在线观看| 亚洲欧洲在线视频| 亚洲婷婷综合久久一本伊一区| 久久久久国产精品麻豆ai换脸| 国产精品一区二区你懂的| 亚洲午夜久久久久久久久电影院| 欧美国产激情| 蜜桃精品久久久久久久免费影院| 国内精品久久久久久影视8 | 国产精品一二一区| 亚洲图片在线| 亚洲最新在线视频| 国产精品电影观看| 亚洲在线观看免费| 亚洲制服丝袜在线| 国产欧美日韩一区二区三区在线观看| 亚洲免费在线观看| 亚洲在线观看免费| 国产视频精品免费播放| 久久久久久久成人| 久久久久久久一区| 亚洲欧洲视频| 99在线精品视频在线观看| 国产精品国产精品| 欧美伊人久久大香线蕉综合69| 午夜亚洲性色福利视频| 韩国福利一区| 欧美第一黄网免费网站| 欧美精品一区三区在线观看| 亚洲视屏一区| 欧美中文字幕视频| 亚洲精品看片| 亚洲在线黄色| 精品成人一区二区| 91久久中文| 中文国产成人精品久久一| 免费在线亚洲| 久久精品综合网| 亚洲第一综合天堂另类专| aⅴ色国产欧美| 老司机免费视频一区二区| 国产精品三级视频| 一区二区三区四区国产| 欧美福利网址| 久久精品国产精品亚洲综合| 国产精品久久国产三级国电话系列| 激情综合激情| 久久精品在线播放| 亚洲免费一在线| 欧美日韩视频第一区| 亚洲国产日韩一区| 蜜臀av国产精品久久久久| 欧美一区二区三区四区在线观看地址 | 亚洲美女av在线播放| 久久综合一区| 一区精品在线| 欧美3dxxxxhd| 蜜桃精品久久久久久久免费影院| 一区二区在线观看视频| 久色成人在线| 久热精品视频在线观看| 亚洲国产成人91精品| 亚洲第一页在线| 欧美成人免费网站| 日韩一二三在线视频播| 亚洲精品视频一区| 国产精品久久精品日日| 欧美影片第一页| 久久精品国产精品| 亚洲区在线播放| 亚洲毛片一区二区| 国产精品自拍一区| 久热精品视频在线| 欧美精品久久久久久久免费观看| a4yy欧美一区二区三区| 国产精品99久久久久久人| 国产美女精品| 欧美a级理论片| 欧美日韩国产影院| 午夜在线一区二区| 久久视频免费观看| 99精品欧美一区二区蜜桃免费| 一区二区三区免费观看| 国产亚洲精品成人av久久ww| 欧美1区2区| 欧美日韩一区二区在线视频| 欧美一区二区三区精品| 久久久久这里只有精品| 99国产精品私拍| 午夜精品一区二区在线观看| 亚洲欧洲在线一区| 久久一区二区三区国产精品 | 亚洲国产aⅴ天堂久久| 亚洲国产精品美女| 国产精品私拍pans大尺度在线| 久久免费精品视频| 欧美日韩成人一区二区三区| 欧美在线中文字幕| 欧美国产日韩精品| 久久国产精品一区二区三区| 欧美14一18处毛片| 久久精品av麻豆的观看方式| 欧美成人免费观看| 久久www免费人成看片高清| 蜜臀91精品一区二区三区| 亚洲免费视频一区二区| 久久久久在线| 欧美在线首页| 欧美视频一区二区三区…| 牛牛影视久久网| 国产日韩一级二级三级| 在线视频精品一区| 91久久国产自产拍夜夜嗨| 先锋影音久久久| 亚洲淫片在线视频| 欧美日本高清视频| 亚洲国产欧美久久| 在线欧美影院| 欧美在线观看你懂的| 亚洲图片你懂的| 欧美日韩国产电影| 亚洲国产视频一区| 最近中文字幕mv在线一区二区三区四区| 午夜日韩视频| 欧美一区二区高清在线观看| 欧美性天天影院| 一区二区三区视频在线| 亚洲午夜在线| 国产精品大片wwwwww| 一区二区三区欧美日韩| 在线视频日韩精品| 欧美日韩在线亚洲一区蜜芽| 91久久久久久久久| 日韩小视频在线观看专区| 欧美丰满高潮xxxx喷水动漫| 欧美激情网站在线观看| 亚洲三级毛片| 欧美理论视频| 中日韩男男gay无套| 亚洲欧美激情四射在线日| 国产精品爱啪在线线免费观看| 一本在线高清不卡dvd| 亚洲欧美影音先锋| 国产精品毛片高清在线完整版| av成人免费| 欧美在线观看一二区| 国产亚洲人成a一在线v站| 欧美影院在线播放| 免费欧美在线| 亚洲三级免费电影| 欧美午夜在线一二页| 亚洲欧美美女| 男同欧美伦乱| 欧美亚洲免费高清在线观看| 美女精品在线| 亚洲精品一区中文| 亚洲一区二区三区乱码aⅴ| 国产精品毛片一区二区三区| 欧美一区成人| 欧美国产日韩在线观看| 国产精品99久久99久久久二8| 国产精品久久久久久久久久ktv| 午夜精品国产更新| 欧美不卡在线| 亚洲欧美精品在线| 伊人春色精品| 欧美色精品天天在线观看视频 | 老司机凹凸av亚洲导航| 亚洲伦理一区| 国产日韩欧美自拍| 欧美成人资源网| 午夜视频一区在线观看| 亚洲第一精品夜夜躁人人爽| 亚洲一区二区三区精品视频 | 性色av一区二区三区在线观看| 伊人影院久久| 国产精品高潮视频| 蜜桃伊人久久| 欧美一区二区三区在线| 亚洲国产成人精品久久| 欧美在线视频在线播放完整版免费观看 | 亚洲第一天堂av| 国产精品免费在线 | 国产亚洲女人久久久久毛片| 欧美激情亚洲精品| 久久久久九九九九| 亚洲欧美日韩国产成人精品影院| 亚洲第一网站免费视频| 久久久久久9999| 欧美一区二区日韩一区二区| 99国产精品99久久久久久粉嫩| 韩国一区二区三区在线观看 | 亚洲高清自拍| 久久婷婷色综合| 欧美一区二区在线免费观看| 一区二区三区黄色| 亚洲精品久久| 亚洲黄色免费| 亚洲国产精品一区二区久|