使用boost.python封装C++库

使用boost.python封装C++库

C++以高性能著称,但是编写较为复杂.而简洁是Python的强项.如果能珠联璧合,就能发挥两家之长.本文尝试用boost库的python模块封装C++

前期准备

需要安装Python和boost库,特别注意的是,在安装boost时,要指明with-python的版本

sudo apt install python3-dev build-essential
git clone https://github.com/boostorg/boost.git
cd boost
./bootstrap.sh --with-python=python3.5 # python3.6的话就写3.6
./b2
sudo ./b2 install

项目结构

➜  py3 tree
.
├── CMakeLists.txt
├── demo.cpp
├── demo.h
└── pymodule.cpp

1. CMakeLists.txt

#CMakeLists.txt
cmake_minimum_required(VERSION 3.5) #CMake的最低版本要求
project(demo)
set(CMAKE_CXX_STANDARD 11)

# 添加Python包
find_package(PythonLibs 3.5 REQUIRED)
include_directories(${PYTHON_INCLUDE_DIR})

# 添加Boost包
find_package(Boost COMPONENTS python3 REQUIRED)
include_directories(${Boost_INCLUDE_DIR})

# 生成动态链接库
set(PYMODULE "cpp_py_module")
set(SOURCE_FILES pymodule.cpp demo.cpp demo.h)
add_library(${PYMODULE} SHARED ${SOURCE_FILES})
target_link_libraries(${PYMODULE} ${Boost_LIBRARIES})
set_target_properties(${PYMODULE} PROPERTIES PREFIX "") # 去掉前缀,否则会生成lib***.so

2. demo.h

//demo.h
#ifndef DEMO_H_
#define DEMO_H_

#include <string>
class Person
{
  public:
    Person(std::string name, int age);
    std::string getName();
    int getAge();
    

  private:
    std::string name;
    int age;
};

double add(double a, double b);

#endif // DEMO_H_

3. demo.cpp

//demo.cpp
#include "demo.h"

Person::Person(std::string name, int age)
{
    this->name = name;
    this->age = age;
}

std::string Person::getName()
{
    return name;
}

int Person::getAge()
{
    return age;
}

double add(double a, double b)
{
    return a + b;
}

4. pymodule.cpp

#include "demo.h"
#include <boost/python.hpp>

// module名要和CMakeLists.txt中生成的so目标名一致
BOOST_PYTHON_MODULE(cpp_py_module)
{
    using namespace boost::python;

    class_<Person>("Person",
                   init<std::string, int>()) // 构造函数
        .def("getName", &Person::getName)  // 成员函数
        .def("getAge", &Person::getAge);

    def("add", add); // 普通函数
}

测试

编译生成动态链接库

cmake .
make

会在当前目录下生成cpp_py_module.so

在当前目录下用python3测试模块

In [1]: import cpp_py_module

In [2]: cpp_py_module.add(4, 5)
Out[2]: 9.0

In [3]: p = cpp_py_module.Person("Jack", 25)

In [4]: p.getName()
Out[4]: 'Jack'

In [5]: p.getAge()
Out[5]: 25

小结

Python作为胶水语言真是名副其实,这样就可以用Python解决输入格式之类的dirty work,然后C++解决密集计算.

使用Boost还有一个好处就是不用修改原来的C++代码,只要外面加一层pymodule.cpp的wrapper就好了,简洁明了.

猜你喜欢

转载自www.cnblogs.com/fanghao/p/9391292.html