學習是一個累積的過程。在這個過程當中,咱們不只要學習新的知識,還須要將之前學到的知識進行回顧總結。python
前面講述了Python使用ctypes直接調用動態庫和使用Python的C語言API封裝C函數, C++寫python擴展模塊有不少種方式,我選擇的是boost.python來編寫的,感受這個要比其餘的方式要簡單不少,本文概述方便封裝C++類給Python使用的boost_python庫。ios
sudo aptitude install libboost-python-dev
下面代碼簡單實現了一個普通函數maxab()和一個Student類:python2.7
#include <iostream> #include <string> int maxab(int a, int b) { return a>b?a:b; } class Student { private: int age; std::string name; public: Student() {} Student(std::string const& _name, int _age) { name=_name; age=_age; } static void myrole() { std::cout << "I'm a student!" << std::endl; } void whoami() { std::cout << "I am " << name << std::endl; } bool operator==(Student const& s) const { return age == s.age; } bool operator!=(Student const& s) const { return age != s.age; } };
使用boost.python庫封裝也很簡單,以下代碼所示:函數
#include <Python.h> #include <boost/python.hpp> #include <boost/python/suite/indexing/vector_indexing_suite.hpp> #include <vector> #include "student.h" using namespace boost::python; BOOST_PYTHON_MODULE(student) { // This will enable user-defined docstrings and python signatures, // while disabling the C++ signatures scope().attr("__version__") = "1.0.0"; scope().attr("__doc__") = "a demo module to use boost_python."; docstring_options local_docstring_options(true, false, false); def( "maxab", &maxab, "return max of two numbers.\n" ); class_<Student>("Student", "a class of student") .def(init<>()) .def(init<std::string, int>()) // methods for Chinese word segmentation .def( "whoami", &Student::whoami, "method's doc string..." ) .def( "myrole", &Student::myrole, "method's doc string..." ) .staticmethod("myrole"); // 封裝STL class_<std::vector<Student> >("StudentVec") .def(vector_indexing_suite<std::vector<Student> >()) ; }
上述代碼仍是include了Python.h文件,若是不include的話,會報錯誤:學習
wrap_python.hpp:50:23: fatal error: pyconfig.h: No such file or directory
編譯以上代碼有兩種方式,一種是在命令行下面直接使用g++編譯:ui
g++ -I/usr/include/python2.7 -fPIC wrap_student.cpp -lboost_python -shared -o student.so
首先指定Python.h的路徑,若是是Python 3的話就要修改成相應的路徑,編譯wrap_student.cpp要指定-fPIC參數,連接(-lboost_python)生成動態庫(-shared)。 生成的student.so動態庫就能夠被python直接import使用了spa
In [1]: import student In [2]: student.maxab(2, 5) Out[2]: 5 In [3]: s = student.Student('Tom', 12) In [4]: s.whoami() I am Tom In [5]: s.myrole() I'm a student!
另一直方法是用python的setuptools編寫setup.py腳本:命令行
#!/usr/bin/env python from setuptools import setup, Extension setup(name="student", ext_modules=[ Extension("student", ["wrap_student.cpp"], libraries = ["boost_python"]) ])
而後執行命令編譯:code
python setup.py build or sudo python setup.py install
學習筆記整理於猿人學教程blog