当前位置: 首页 > 科技观察

打通Python和C++之后?你知道!

时间:2023-03-16 20:51:20 科技观察

Python是世界上最好的胶水语言(呵呵,世界上最好的语言当然是PHP==),利用Python的简单和C++的高效,基本可以解决99%的问题~General是的,Python和C++的交互分为两种情况:ExtendingPythonwithC++:当Python项目出现性能瓶颈时,将瓶颈部分提取出来,用C++打包成Python可以调用的模块(solibrary);EmbedPythonintoC++:当C++项目中的某些功能预计会经常变化,并期望有更高的灵活性时,将这些功能用Python实现,并在C++中调用。本文将在第一部分简单介绍一个实践。Boost.PythonBoost作为一个大宝库,提供了我们需要的这个功能。而且,在Boost的很多库中,已经默认使用了Boost.Python,所以也经过了充分的测试。安装Boost的大部分函数都是以头文件的形式提供的,不需要安装;但是,也有一些函数需要手动编译。不幸的是,Boost.Python也是其中之一。按照UnixVariants入门的第五部分安装Boost.Python。安装完成后可以在相关目录下看到相关的so文件(我的是在/usr/local/lib下)。HelloWorld在C++中实现了一个模块,在Python中调用时可以返回特定的字符串。++#includecharconst*greet(){return"hello,boost";}BOOST_PYTHON_MODULE(hello_boostpy){usingnamespaceboost::python;def("greet",greet);}太简单了,code基本说明了一切~编译成动态链接库:g++-I/usr/include/python2.7/-fPIC-shared-ohello_boostpy.sohello_boostpy.cc-lboost_python这时候可以用ldd看看hello_boostpy.so可以你可以找到libboost_python。如果找不到,需要手动将其路径添加到环境变量LD_LIBRARY_PATH中,或者使用ldconfig相关命令。接下来,您可以在Python中使用hello_boostpy库:#-*-coding:utf-8-*-importsyssys.path.append('.')deftest():importhello_boostpyreturnhello_boostpy.greet()if__name__=="__main__":printtest()ExposeClass接下来,我们在C++实现的模块中添加一个类,并尝试将Python列表类型对象传递给C++。C++类:++#include#include#include#includeusingnamespaceboost::python;structPerson{voidset_name(std::stringname){this->name=name;}std::stringprint_info();voidset_items(list&prices,list&discounts);std::stringname;std::vectoritem_prices;std::vectoritem_discounts;};其中,Python端的list类型,在Boost.Python中有对应的实现boost::python::list(对应的,dict、tuple等类型也有对应的实现)。在set_items中,我们将使用boost::python::extract进行数据类型的转换。++voidPerson::set_items(list&prices,list&discounts){for(inti=0;i(prices[i]);doublediscount=extract(discounts[i]);item_prices.push_back(price);item_discounts.push_back(discount);}}Python模块定义部分还是很直观的代码:BOOST_PYTHON_MODULE(person){class_("Person").def("set_name",&Person::set_name).def("print_info",&Person::print_info).def("set_items",&Person::set_items);}在Python代码中,可以使用Python定义的类使用Person类:#-*-coding:utf-8-*-importsyssys.path.append('.')deftest():importpersonp=person.Person()p.set_name('切')p.set_items([100,123.456,888.8],[0.3,0.1,0.5])printp.print_info()if__name__=="__main__":test()Py++上面的模块封装过程看起来还是有些枯燥,很多地方都是重复的工作。那么可以自动完成吗?Py++提供了这样的能力,可以帮你自动生成Boost.Python相关代码。对于接口较多的模块,可以大大减少工作量,减少错误。概率。具体使用请参考教程