恒泰博远,专家级研发软件定制开发公司,为企业定制营销、办公、管理软件 在线咨询 :
咨询电话:010-82969001

C++ 嵌入、扩展Python的开发库 ffpython

来源:http://www.hengtaiboyuan.com 作者:恒泰博远 时间:2014-08-29

[摘要]Python 是最流行的脚本之一,并且python拥有定义良好的C API接口,同时又有丰富的文档,与C++结合非常的适合。通常情况下使用C++封装机制,而用python脚本实现策略或者是控制。使用python和C++结合的技术拥有如下优势

Python 是最流行的脚本之一,并且python拥有定义良好的C API接口,同时又有丰富的文档,与C++结合非常的适合。通常情况下使用C++封装机制,而用python脚本实现策略或者是控制。使用python和C++结合的技术拥有如下优势:

 1、 主体系统使用C++实现,保持系统的高效。 

  2、  控制部分使用python,增加开发效率,python的内存垃圾回收,丰富的类库都使C++开发者获益匪浅。 

  3、 Python脚本可以运行期重载,可以实现控制部分不停机热更新。 

 

C++与python的编程范式有很大不同,当使用python C API调用python时,python中的一些特有机制会给C++开发者带来很多困惑。常常使用python C API时需要注意如下几点:

1、 Python 使用引用计数管理内存,调用python C API时对于返回值返回的是借用的引用还是新的引用,需要根据文档仔细确认。否则轻则出现内存泄露,重则程序崩溃。 

 2、Python中的数据结构与C++的有很大不同。Python常用的有tuple,list,dict。而c++常用的事 vector,list,map,并且c++是强类型的。当c++与python进行交互时,C++层希望操作python数据结构就像操作c++ STL一样方便,而在python脚本层,又希望c++传入的参数或返回值都是原生的python数据 

 3、 C++中常用的指针传递对象,当嵌入python时,需要把c++对象传递到python中。

 

ffpython是专门方便C++嵌入python开发的类库,基于ffpython一方面可以轻松的将python集成到C++系统,另一方面,C++对象或接口也可以很容易被python使用,总之ffpython简化了c++与python的交互操作。

    ffpython 是轻量级的,只有一个头文件,并且增加了一个方便阅读的版本,可以供想要嵌入python的开发者参考。

异常

 

用户可以catch标准异常,what接口返回的字符串包含了异常的traceback信息方便排查错误。示例如下:

 

 

扩展python

 

ffpython 可以注册static函数到python中,全局的C风格的static函数和类中定义的static函数都可以被注册到python中,示例如下:

 

 

c++类注册到python

 

class foo_t

{

public:

    foo_t(int v_):m_value(v_)

    {

        printf("%s\n", __FUNCTION__);

    }

    virtual ~foo_t()

    {

        printf("%s\n", __FUNCTION__);

    }

    int get_value() const { return m_value; }

    void set_value(int v_) { m_value = v_; }

    void test_stl(map<string, list<int> >& v_) 

    {

        printf("%s\n", __FUNCTION__);

    }

    int m_value;

};

class dumy_t: public foo_t

{

public:

    dumy_t(int v_):foo_t(v_)

    {

        printf("%s\n", __FUNCTION__);

    }

    ~dumy_t()

    {

        printf("%s\n", __FUNCTION__);

    }

    void dump() 

    {

        printf("%s\n", __FUNCTION__);

    }

};

static foo_t* obj_test(dumy_t* p)

{

    printf("%s\n", __FUNCTION__);

    return p;

}

void test_register_base_class(ffpython_t& ffpython)

{

    ffpython.reg_class<foo_t, PYCTOR(int)>("foo_t")

            .reg(&foo_t::get_value, "get_value")

            .reg(&foo_t::set_value, "set_value")

            .reg(&foo_t::test_stl, "test_stl")

            .reg_property(&foo_t::m_value, "m_value");

    ffpython.reg_class<dumy_t, PYCTOR(int)>("dumy_t", "dumy_t class inherit foo_t ctor <int>", "foo_t")

        .reg(&dumy_t::dump, "dump");

    ffpython.reg(obj_test, "obj_test");

    ffpython.init();

    ffpython.call<void>("fftest", "test_register_base_class");

};