时间:2021-05-22
前言
学习中如果碰到问题,参考官网例子:
D:\boost_1_61_0\libs\python\test
参考:Boost.Python 中英文文档。
利用Boost.Python实现Python C/C++混合编程
关于python与C++混合编程,事实上有两个部分
两者都可以用 python c 转换api,解决,具体可以去python官方文档查阅,但是都比较繁琐.
对于1,extending,常用的方案是boost.python以及swig.
swig是一种胶水语言,粘合C++,PYTHON,我前面的图形显示二叉树的文章中提到的就是利用pyqt作界面,调用c++代码使用swig生成的.so动态库.
而boost.python则直接转换,可以利用py++自动生成需要的wrapper.关于这方面的内容的入门除了boost.python官网,中文的入门资料推荐
下面话不多说了,来一起看看详细的介绍吧
导出函数
python:
import hello_extprint hello_ext.greet()导出类:
导出默认构造的函数的类
c++
#include<string>#include<boost/python.hpp>using namespace std;using namespace boost::python;struct World{ void set(string msg) { this->msg = msg; } string greet() { return msg; } string msg;};BOOST_PYTHON_MODULE(hello) //导出的module 名字{ class_<World>("World") .def("greet", &World::greet) .def("set", &World::set);}python:
import hello planet = hello.World() # 调用默认构造函数,产生类对象planet.set("howdy") # 调用对象的方法print planet.greet() # 调用对象的方法构造函数的导出:
python 测试调用:
import helloplanet = hello.World(5,6)planet2 = hello.World("hollo world")print planet.sum_s()print planet2.greet()如果不想导出任何构造函数,则使用no_init:
class_<Abstract>("Abstract",no_init)类的数据成员
python调用:
import hello_varvar = hello_var.Var("hello_var")var.value = 3.14# var.name = 'hello' # errorprint var.nameC++类对象导出为Python的类对象,注意var.name不能赋值。
类的属性
python:
import hello_numnum = hello_num.Num()num.value = 10print num.rovalue # result: 10继承
python:
import hello_derivedderive = hello_derived.factory()hello_derived.d(derive)类的虚函数:
python:
import hello_virtualbase = hello_virtual.Base()# 定义派生类,继承C++类class Derived(hello_virtual.Base): def f(self): return 42derived = Derived()print base.f()print derived.f()类的运算符/特殊函数
注意上面的:.def(pow(self, other<FilePos>()))模板后面要加上括号。也要注意头文件的包含,否则会引发错误。
python:
import hello_operatorfilepos1 = hello_operator.FilePos()filepos1.len = 10filepos2 = hello_operator.FilePos()filepos2.len = 20;print filepos1 - filepos2函数
函数的调用策略。
// 函数的调用策略#include<string>#include<iostream>#include<boost/python.hpp>using namespace std;using namespace boost::python;struct X{ string str;};struct Z{ int value;};struct Y{ X x; Z *z; int z_value() { return z->value; }};X & f(Y &y, Z*z){ y.z = z; return y.x; //因为x是y的数据成员,x的声明周期与y进行了绑定。因为我们的目的是:Python接口应尽可能的反映C++接口}BOOST_PYTHON_MODULE(hello_call_policy){ class_<Y>("Y") .def_readwrite("x", &Y::x) .def_readwrite("z", &Y::z) .def("z_value", &Y::z_value); class_<X>("X") .def_readwrite("str", &X::str); class_<Z>("Z") .def_readwrite("value", &Z::value); // return_internal_reference<1 表示返回的值与第一个参数有关系:即第一个参数是返回对象的拥有者(y和x都是引用的形式)。 // with_custodian_and_ward<1, 2> 表示第二个参数的生命周期依赖于第一个参数的生命周期。 def("f", f, return_internal_reference<1, with_custodian_and_ward<1, 2> >());}函数重载
python:
import hello_overloadedx = hello_overloaded.X() # create a new objectprint x.f(1) # default int typeprint x.f(2,double(3))print x.f(4,double(5),chr(6)) # chr(6) convert * to char print x.f(7,8,9)默认参数
普通函数的默认参数:
然而通过上面的方式对重载函数进行封装时,就丢失了默认参数的信息。当然我们可以通过一般形式的封装,如下:
int f(int,double = 3.14,char const * = "hello");int f1(int x){ return f(x);}int f2(int x,double y){return f(x,y)}//int module initdef("f",f); // 所有参数def("f",f2); //两个参数def("f",f1); //一个参数但是通过上面的形式封装很麻烦。我们可以通过宏的形式,为我们批量完成上面的功能。
C++:
成员函数的默认参数:
//使用BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS 宏,完成成员函数默认参数的接口#include<string>#include<iostream>#include<boost/python.hpp>using namespace std;using namespace boost::python;struct george{ void wack_em(int a, int b = 0, char c = 'x') { return; }};BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(george_overloads, wack_em, 1, 3); // 参数个数的最小为1,最大为3BOOST_PYTHON_MODULE(hello_member_overloaded){ class_<george>("george") .def("wack_em", &george::wack_em, george_overloads());}python:
import hello_member_overloadedc = hello_member_overloaded.george()c.wack_em(1)c.wack_em(1,2)c.wack_em(1,2,chr(3))利用init和optional实现构造函数的重载。
使用方法如下:
对象接口
Python 是动态类型的语言,C++是静态类型的。Python变量可能是:integer,float ,list ,dict,tuple,str,long,等等,还有其他类型。从Boost.Python和C++的观点来看,Python中的变量是类object的实例,在本节,我们看一下如何处理Python对象。
基本接口
// init optional#include<string>#include<iostream>#include<boost/python.hpp>#include <numpy/arrayobject.h>using namespace std;using namespace boost::python;namespace bp = boost::python;void f(object x){ int y = extract<int>(x); // retrieve an int from x}int g(object x){ extract<int> get_int(x); if (get_int.check()) return get_int(); else return 0;}int test(object &x){ dict d = extract<dict>(x.attr("__dict__")); d["whatever"] = 4; return 0;}int test2(dict & d){ d["helloworld"] = 3; return 0;}class A {public: list lst; void listOperation(list &lst) {};};// 传入np.array数组对象,让C++进行处理int add_arr_1(object & data_obj, object rows_obj, object cols_obj){ PyArrayObject* data_arr = reinterpret_cast<PyArrayObject*>(data_obj.ptr()); float * data = static_cast<float *>(PyArray_DATA(data_arr)); // using data int rows = extract<int>(rows_obj); int cols = extract<int>(cols_obj); for (int i = 0; i < rows*cols; i++) { data[i] += 1; } return 0;}BOOST_PYTHON_MODULE(hello_object){ def("test", test); def("test2", test2); def("add_arr_1", add_arr_1);}python 调用:
import hello_objectdic1 = {"whatever":1}hello_object.test2(dic1)arr = np.array([1,2,3],dtype = float32)print arr.dtypeprint arrhello_object.add_arr_1(arr,1,3)print arr总结:
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
我是在ubuntu系统进行实验的,所以和window可能会有区别。python调用C/C++有不少的方法,如boost.python,swig,ctypes,p
python调用C/C++有不少的方法,如boost.python,swig,ctypes,pybind11等,这些方法有繁有简,而pybind11的优点是对C
python网络编程详解网络编程的专利权应该属于Unix,各个平台(如windows、Linux等)、各门语言(C、C++、Python、Java等)所实现的符
最近项目使用c++操作Python脚本,选用boost.python库。在window下编译安装很顺利,但是在Linux下一直编译不通过,总是提示找不到头文件。
在工作中,C、C++密不可分,做我们嵌入式方面的,当然更多的是C,但,有时候却少不了C++,而且是C、C++混搭(混合编程)在一起的,比如,RTP视频传输,li