很久没有写文章了, 今天整理了一些东西, 在这里分享一下.
最近一直在想用 C++ 封装一些在工作中常用的 Python 扩展模块, 因为之前没有用 C++ 写过类似的东西, 因此一直在网上找一些文章, 但是我发现好多文章都描述的不是很清晰, 对于老鸟来说应该会很容易, 但是像我这种初学者, 肯定会造成很大的困扰, 因为总是出现很多的报错, 搞的头很大, 因此我将成功的案例分享一下, 并且详细的解释下让我产生疑惑的地方.
boost.python
简单描述
C++ 写 python 扩展模块有很多种方式, 我选择的是 boost.python 来编写的, 感觉这个要比其他的方式要简单很多, 写很少的 boost.python 代码就可以, 这样就可以更专注的去写 C++ 的程序.
boost.python 的科普就不必多说了, 可以自行 google, 我也是自己 google 的.
安装
这里仅介绍 Ubuntu 的安装方式:
sudo apt-get install libboost-all-dev
或者
- sudo apt-get install libboost-python-dev
- # 这种方式我没有尝试, 你们可以自己试试
源码安装也是可以的, 但是需要配置好环境变量, 否则编译的时候总是编译不过去, 当前直接在编译的时候指定需要的路径也是可以的.
实例
C++ 代码
下面的例子将一些模糊的点, 做了一下描述.
- #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 岁了
如果文章中步骤有不对的地方的话, 请指出, 我会在最快的时间内修改好, 谢谢.
来源: http://www.bubuko.com/infodetail-2716227.html