打通Python和C++之后?你懂的!

Python作为世界上***的打通懂 胶水 语言(哼,世界上***的打通懂语言当然是PHP==),利用Python的打通懂简洁和C++的高效,基本可以解决99%的打通懂问题了吧~

一般的,Python和C++的打通懂交互分为这两种情况:

用C++扩展Python:当一个Python项目中出现了性能瓶颈时,将瓶颈部分抽离出来,打通懂用C++封装成一个Python可以调用的打通懂模块(so库); 将Python内嵌入C++:当一个C++项目中有部分功能预期将会经常变更需求,期望获得更高的打通懂灵活性时,将这部分功能用Python实现,打通懂在C++中进行调用。打通懂这篇文章将简单介绍下***部分的打通懂一种做法。

Boost.Python

Boost作为一个大宝库,打通懂提供了我们所需要的打通懂这一功能。并且,打通懂在Boost的打通懂许多库中,已经默认使用了Boost.Python,所以也算是经过了充分的测试。

安装

Boost的大部分功能都是高防服务器以头文件的形式提供的,无需安装;但是也有少部分功能,需要进行手动编译。不幸,Boost.Python也是其中之一。

参照 Getting Started on Unix Variants 的第五部分内容,即可安装Boost.Python。安装完成后,可以在相关目录(我的是/usr/local/lib下)看到相关的so文件。

Hello World

用C++实现一个模块,在Python中调用时,可以返回一个特定的字符串。

++

#include <boost/python.hpp> char const* greet() {      return "hello, boost"; } BOOST_PYTHON_MODULE(hello_boostpy) {      using namespace boost::python;     def("greet", greet); } 

太简单了,代码基本说明了一切~

将其编译成动态链接库的形式:

g++ -I /usr/include/python2.7/ -fPIC -shared -o hello_boostpy.so hello_boostpy.cc -lboost_python 

这时可以使用ldd看看hello_boostpy.so可不可以找到libboost_python,找不到的话,需要手动将其路径加入环境变量LD_LIBRARY_PATH中,或者用ldconfig相关的命令也可以。

接下来就可以在Python中使用hello_boostpy库了:

# -*- coding: utf-8 -*- import sys sys.path.append(.) def test():     import hello_boostpy     return hello_boostpy.greet() if __name__ == "__main__":     print test() 

Expose Class

接下来,我们在C++实现的模块中,添加一个类,源码库并且尝试向C++方向传入Python的list类型对象。

C++类:

++

#include <boost/python.hpp> #include <vector> #include <string> #include <sstream> using namespace boost::python; struct Person {      void set_name(std::string name) {  this->name = name; }     std::string print_info();     void set_items(list& prices, list& discounts);     std::string name;     std::vector<double> item_prices;     std::vector<double> item_discounts; }; 

其中,Python方的list类型,在Boost.Python中有一个对应的实现boost::python::list(相应的,dict、tuple等类型都有对应实现)。在set_items中,我们将会用boost::python::extract对数据类型做一个转换。

++

void Person::set_items(list& prices, list& discounts) {      for(int i = 0; i < len(prices); ++i)     {          double price = extract<double>(prices[i]);         double discount = extract<double>(discounts[i]);         item_prices.push_back(price);         item_discounts.push_back(discount);     } } 

Python模块定义部分依旧是非常直观的代码:

BOOST_PYTHON_MODULE(person) {      class_<Person>("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 -*- import sys sys.path.append(.) def test():     import person     p = person.Person()     p.set_name(Qie)     p.set_items([100, 123.456, 888.8], [0.3, 0.1, 0.5])     print p.print_info() if __name__ == "__main__":     test() 

Py++

上面的模块封装过程,看上去还是有些枯燥,有不少地方都是重复的工作。那么可不可以自动的进行呢?Py++提供了这样的能力,它可以帮你自动生成Boost.Python的相关代码,对于接口数量比较多的模块来说,可以极大的减少工作量,也减少了出错的香港云服务器概率。具体使用方法,可以参见 Tutorial

系统运维
上一篇:数据中心如何选址和维护?
下一篇:2032年,数据中心市场规模预计达到2098亿美元