C/C++培训
达内IT学院
400-996-5531
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][#/doc/libs/1_65_1/more/getting_started/unix-variants.html] 的第五部分内容,即可安装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][#/en/latest/tutorials/module_builder/module_builder.html]
Boost.Python的更多内容,参见[官方文档][#/doc/libs/1_65_1/libs/python/doc/html/reference/index.html]
[Tutorial][#/doc/libs/1_65_1/libs/python/doc/html/tutorial/index.html]
本文内容转载自网络,本着分享与传播的原则,版权归原作者所有,如有侵权请联系我们进行删除!
填写下面表单即可预约申请免费试听!怕钱不够?可就业挣钱后再付学费! 怕学不会?助教全程陪读,随时解惑!担心就业?一地学习,可全国推荐就业!
Copyright © 京ICP备08000853号-56 京公网安备 11010802029508号 达内时代科技集团有限公司 版权所有
Tedu.cn All Rights Reserved