好久没有写文章了,今天整理了一些东西,在这里分享一下。python
最近一直在想用C++封装一些在工做中经常使用的Python扩展模块,由于以前没有用C++写过相似的东西,所以一直在网上找一些文章,可是我发现好多文章都描述的不是很清晰,对于老鸟来讲应该会很容易,可是像我这种初学者,确定会形成很大的困扰,由于老是出现不少的报错,搞的头很大,所以我将成功的案例分享一下,而且详细的解释下让我产生疑惑的地方。ios
简单描述python2.7
C++写python扩展模块有不少种方式,我选择的是boost.python来编写的,感受这个要比其余的方式要简单不少,写不多的boost.python代码就能够,这样就能够更专一的去写C++的程序。ide
boost.python的科普就没必要多说了,能够自行google,我也是本身google的。函数
安装测试
这里仅介绍Ubuntu的安装方式:google
sudo apt-get install libboost-all-dev
或者spa
sudo apt-get install libboost-python-dev # 这种方式我没有尝试,大家能够本身试试
源码安装也是能够的,可是须要配置好环境变量,不然编译的时候老是编译不过去,当前直接在编译的时候指定须要的路径也是能够的。code
C++ 代码get
下面的例子将一些模糊的点,作了一下描述。
#include <iostream> #include <string> #include <boost/python.hpp> // 必须引入这个头文件 using namespace boost::python; class HelloWorld{ public: HelloWorld(const std::string& name, int age); void printInfo(); private: std::string m_name; int m_age; }; HelloWorld::HelloWorld(const std::string& name, int age):m_name(name), m_age(age){ } void HelloWorld::printInfo(){ std::cout << "我叫" << m_name << ", " << m_age << "岁了" << std::endl; } void ceshi(){ std::cout << "ceshi" << std::endl; } BOOST_PYTHON_MODULE(helloworld){ // 类导出成Python可调用的动态连接库文件的方式 class_<HelloWorld/* 类名 */, boost::noncopyable /* 单例模式,无关紧要 */ > ("helloworld", init<const std::string&, int/* init里面就是放构造函数的参数,不须要实参 */>())//导出类中的方法 .def("printinfo", &HelloWorld::printInfo); // 普通函数导出成Python可调用的动态连接库文件的方式 def("ceshi",&ceshi); }
编译的命令
下面的命令是我在编译动态连接库文件的命令,根据本身的实际状况修改。
# python3 g++ -shared -o helloworld.so -fPIC -I/usr/include/python3.6m/ helloworld.cpp -lpython3.6m -lboost_python3 # python2 g++ -shared -o helloworld.so -fPIC -I/usr/include/python2.7/ helloworld.cpp -lpython -lboost_python 简单介绍下参数 -shared // 指定生成动态连接库 -o // 生成的动态连接库的名称 -fPIC // 表示使用地址无关代码 -I(大写的i) // 表示将/usr/include/python2.7/目录做为第一个寻找头文件的目录、 -l // 指定需链接的库名
没有报错的话会在当前目录下生成一个名叫helloworld.so
的动态连接库文件,直接在当前目录进入Python Shell就能够测试,固然你直接放入到Python的site-packages目录中也是能够直接在Python Shell环境中引入的。
验证结果
>>> import helloworld >>> hw = helloworld.helloworld("lanyulei", 18) >>> hw.printinfo() 我叫lanyulei, 18岁了