php下载站源码长沙专业做网络的公司
php下载站源码,长沙专业做网络的公司,邯郸网站制作建设,成品短视频app下载有哪些软件好C使用ffpython嵌入和扩展python#xff08;python2和python3#xff09;摘要:在服务器编程中#xff0c;经常会用到python脚本技术。Python是最流行的脚本之一#xff0c;并且python拥有定义良好的C API接口#xff0c;同时又有丰富的文档#xff0c;与C结合非常的适合。…C使用ffpython嵌入和扩展pythonpython2和python3摘要:在服务器编程中经常会用到python脚本技术。Python是最流行的脚本之一并且python拥有定义良好的C API接口同时又有丰富的文档与C结合非常的适合。通常情况下使用C封装机制而用python脚本实现策略或者是控制。使用python和C结合的技术拥有如下优势主体系统使用C实现保持系统的高效。控制部分使用python增加开发效率python的内存垃圾回收丰富的类库都使C开发者获益匪浅。Python脚本可以运行期重载可以实现控制部分不停机热更新。C与python的编程范式有很大不同当使用python C API调用python时python中的一些特有机制会给C开发者带来很多困惑。常常使用python C API时需要注意如下几点:Python 使用引用计数管理内存调用python C API时对于返回值返回的是借用的引用还是新的引用需要根据文档仔细确认。否则轻则出现内存泄露重则程序崩溃。Python中的数据结构与C的有很大不同。Python常用的有tuplelistdict。而c常用的事vectorlistmap并且c是强类型的。当c与python进行交互时C层希望操作python数据结构就像操作c STL一样方便而在python脚本层又希望c传入的参数或返回值都是原生的python数据C中常用的指针传递对象当嵌入python时需要把c对象传递到python中。 ffpython是专门方便C嵌入python开发的类库基于ffpython一方面可以轻松的将python集成到C系统另一方面C对象或接口也可以很容易被python使用总之ffpython简化了c与python的交互操作。嵌入python最简单的使用python的方式是把python脚本当作配置如获取脚本中的一个字符串变量。Python的脚本文件会被python虚拟机import为module和python的标准库的module实际上是相似的概念。ffpython封装了获取python module中的变量的操作。printf(sys.version%sn, ffpython.get_global_varstring(sys, version).c_str());
上面的代码获取python标准库中sys的version变量值ffpython通过模板函数的自动将python的str类型自动适配到c的string类型。get_global_var是获取变量的接口与之对应的是设置变量的借口get_global_varffpython.get_global_var(fftest, global_var, OhNice);
printf(fftest.global_var%sn, ffpython.get_global_varstring(fftest, global_var).c_str());
调用python函数是嵌入python非常常用的操作ffpython中提供了call接口用于调用python中的module的函数printf(time.asctime%sn, ffpython.callstring(time, asctime).c_str());
上面的代码调用time模块的asctime方法我们也可以使用call接口调用我们自己编写的函数int a1 100; float a2 3.14f; string a3 OhWell;
ffpython.callvoid(fftest, test_base, a1, a2, a3);
Call被定义为模版函数传入的参数会自动适配到python相应的类型。对应的python函数为def test_base(a1, a2, a3):print(test_base, a1, a2, a3)return 0
上面的python函数接受三个参数c传入了三个标准类型参数实际上call接口最多支持9个泛型参数常用的stl 参数是被支持的void test_stl(ffpython_t ffpython)
{vectorint a1;a1.push_back(100);a1.push_back(200);liststring a2; a2.push_back(Oh);a2.push_back(Nice);vectorliststring a3;a3.push_back(a2);ffpython.callbool(fftest, test_stl, a1, a2, a3);
}
对应调用的python函数为def test_stl(a1, a2, a3):print(test_stl, a1, a2, a3)return True
不但STL泛型被支持嵌套定义的类似vector 的结构都是被支持的vector和list都会转换成python的list结构而map则转换为dict结构。调用call接口必须指定接收的返回值类型可以使用void忽略返回值除了可以使用标准类型stl接口也可以被使用python中的tuple和list可以转换成vector和listdict则可以被转换成map。需要注意的是若类型没有匹配call函数将会抛出异常。用户可以catch标准异常what接口返回的字符串包含了异常的traceback信息方便排查错误。示例如下try{......}catch(exception e){printf(exception traceback %sn, e.what());}扩展pythonffpython 可以注册static函数到python中全局的C风格的static函数和类中定义的static函数都可以被注册到python中示例如下 static int print_val(int a1, float a2, const string a3, const vectordouble a4)
{printf(%s[%d,%f,%s,%d]n, __FUNCTION__, a1, a2, a3.c_str(), a4.size());return 0;
}
struct ops_t
{static listint return_stl(){listint ret;ret.push_back(1024);printf(%sn, __FUNCTION__);return ret;}
};std::string test_reg_function(ffpython_t ffpython)
{ffpython.reg(print_val, print_val).reg(ops_t::return_stl, return_stl);ffpython.reg_classfoo_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_classdumy_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);return cppext;
}
以上代码注册了两个接口给python然后调用fftest文件中的test_reg_function测试两个接口fftest.py中定义测试代码def test_reg_function():import ext1ext1.print_val(123, 45.6 , ----789---, [3.14])ret ext1.return_stl()print(test_reg_function, ret)
这两个接口虽然简单但是说明了ffpython注册的接口支持多个参数参数类型可以是标准C类型也可以是STL泛型。同样返回值的类型也是如此。使用ffpython 注册C的对象也很容易ffpython支持注册c类的构造函数成员变量成员方法到python示例代码如下class foo_t
{
public:foo_t(int v_):m_value(v_){printf(%sn, __FUNCTION__);}virtual ~foo_t(){printf(%sn, __FUNCTION__);}int get_value() const { return m_value; }void set_value(int v_) { m_value v_; }void test_stl(mapstring, listint v_) {printf(%sn, __FUNCTION__);}int m_value;
};class dumy_t: public foo_t
{
public:dumy_t(int v_):foo_t(v_){printf(%sn, __FUNCTION__);}~dumy_t(){printf(%sn, __FUNCTION__);}void dump() {printf(%sn, __FUNCTION__);}
};static foo_t* obj_test(dumy_t* p)
{printf(%sn, __FUNCTION__);return p;
}
当c类型被注册到python中后python中使用该类型就像python内建的类型一样方便需要注意的是如果python中动态的创建了c对象那么他是被python的GC管理生命周期的所以当变量不在被引用时c对象的析构函数被调用。对应的fftest.py中测试的脚本代码为def test_register_base_class():import ext2foo ext2.foo_t(20130426)print(test_register_base_class get_val:, foo.get_value())foo.set_value(778899)print(test_register_base_class get_val:, foo.get_value(), foo.m_value)foo.test_stl({key: [11,22,33] })print(test_register_base_class test_register_base_class, foo)
同前边所诉的原则相同支持C 标准内建类型和STL 泛型。当这个python函数返回时foo_t的析构函数会被调用。dumy_t是foo_t的子类。使用ffpython可以方便表示两个类型的关系。如果基类已经定义的接口子类不需要重复定义比如要注册子类ffpython.reg_classdumy_t, PYCTOR(int)(dumy_t, dumy_t class inherit foo_t ctor int, foo_t).reg(dumy_t::dump, dump);void test_register_inherit_class(ffpython_t ffpython)
{ffpython.callvoid(fftest, test_register_inherit_class);
};
只需要单独注册一下子类特有的接口其他接口自动从foo_t基类中继承而来相应的测试python脚本代码为def test_register_inherit_class():import ext2dumy ext2.dumy_t(20130426)print(test_register_inherit_class get_val:, dumy.get_value())dumy.set_value(778899)print(test_register_inherit_class get_val:, dumy.get_value(), dumy.m_value)dumy.test_stl({key: [11,22,33] })dumy.dump()print(test_register_inherit_class, dumy)
ffpython中一个非常用用的特性是c创建的对象可以传递到python中而python使用起来就像正常的python对象一样另外python创建的c对象也可以传递到c中简单示例代码ffpython.reg(obj_test, obj_test);void test_cpp_obj_to_py(ffpython_t ffpython)
{foo_t tmp_foo(2013);ffpython.callvoid(fftest, test_cpp_obj_to_py, tmp_foo);
}void test_cpp_obj_py_obj(ffpython_t ffpython)
{dumy_t tmp_foo(2013);foo_t* p ffpython.callfoo_t*(fftest, test_cpp_obj_py_obj, tmp_foo);
}
相应的fftest.py中的测试脚本代码为def test_cpp_obj_to_py(foo):import ext2print(test_cpp_obj_to_py get_val:, foo.get_value())foo.set_value(778899)print(test_cpp_obj_to_py get_val:, foo.get_value(), foo.m_value)foo.test_stl({key: [11,22,33] })print(test_cpp_obj_to_py test_register_base_class, foo)def test_cpp_obj_py_obj(dumy):import ext2print(test_cpp_obj_py_obj get_val:, dumy.get_value())dumy.set_value(778899)print(test_cpp_obj_py_obj get_val:, dumy.get_value(), dumy.m_value)dumy.test_stl({key: [11,22,33] })dumy.dump()ext2.obj_test(dumy)print(test_cpp_obj_py_obj, dumy)return dumy
总结ffpython 支持c调用python函数获取和设置模块内的变量ffpython call接口最多支持9个泛型参数支持的类型包括c内建的类型和STL 泛型。以及已经被注册的c类的指针类型。返回值的类型约束同样如此。c STL中的vector和list对应于python的tuple和listmap类型则对应于dict。ffpython支持将c的静态函数注册到python中。ffpython支持c类的注册并且支持继承。Python中操作c对象就像操作原生python对象一样。ffpython注册的c类在python中被创建后将会由python GC负责回收内存。ffpython 类库只有一个文件并且不依赖其他第三方库非常容易集成到项目中。而且ffpython遵从开源协议。ffpython使用c模板技术封装了python C API的使用细节保持精巧和简洁效率和完全的python C API编写的代码几乎相同。ffpython的实现可以作为非常好的python C API的示例。Github项目地址https://github.com/fanchy/ffpython 更多文章 http://h2cloud.org
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/88359.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!