首先定义一个动物类(include/animal.h)python
#pragma once #include <string> class Animal { public: Animal(std::string name); virtual ~Animal(); virtual void call(); virtual void move(); void eat(std::string food); protected: std::string name_; };
其实现代码以下(src/animal.cpp)ios
#include <iostream> #include "animal.h" Animal::Animal(std::string name):name_(name) { } Animal::~Animal() { } void Animal::call() { std::cout << name_ << ": call" << std::endl; } void Animal::move() { std::cout << name_ << ": moving" << std::endl; } void Animal::eat(std::string food) { std::cout << name_ << ": eat " << food << std::endl; }
接着编写其导出代码(include/boost_wrapper.h)编程
#pragma once #include <boost/python/wrapper.hpp> #include "animal.h" class AnimalWrap: public Animal, public boost::python::wrapper<Animal> { public: AnimalWrap(std::string name); virtual ~AnimalWrap(); void call(); void move(); };
其导出实现以下(src/boost_wrapper.cpp)app
#include <boost/python/module.hpp> #include <boost/python/class.hpp> #include "boost_wrapper.h" using namespace boost::python; using namespace boost::python::detail; AnimalWrap::AnimalWrap(std::string name):Animal(name) { } AnimalWrap::~AnimalWrap() { } void AnimalWrap::call() { if (override func = this->get_override("call")) func(); Animal::call(); } void AnimalWrap::move() { if (override func = this->get_override("move")) func(); Animal::move(); } BOOST_PYTHON_MODULE_INIT(boost) { class_<AnimalWrap, boost::noncopyable>("Animal", init<std::string>()) .def("call", &Animal::call) .def("move", &Animal::move) .def("eat", &Animal::eat); }
最后编写CMakeLists.txtide
cmake_minimum_required(VERSION 2.8) project(boost) set(CMAKE_CXX_FLAGS "-Wall -g") ### 此处的动态库名必须和BOOST_PYTHON_MODULE()中定义的保持一致,即最后生成的库必须名为boost.so file(GLOB SRC "src/*.cpp") add_library(boost SHARED ${SRC}) set_target_properties(boost PROPERTIES PREFIX "") #dependencies INCLUDE(FindPkgConfig) pkg_check_modules(PYTHON REQUIRED python) include_directories(include /usr/local/include ${PYTHON_INCLUDE_DIRS}) link_directories(/usr/local/lib ${PYTHON_LIBRARY_DIRS}) target_link_libraries(boost boost_python)
项目最终目录结构测试
# tree . . ├── build ├── CMakeLists.txt ├── include │ ├── animal.h │ └── boost_wrapper.h └── src ├── animal.cpp └── boost_wrapper.cpp 3 directories, 5 files
编译ui
# cd build # cmake .. # make
编写测试文件(build/zoo.py)this
import boost def show(): wolf = boost.Animal("wolf") wolf.eat("beef") goat = boost.Animal("gota") goat.eat("grass") if __name__ == '__main__': show()
执行测试spa
# cd build # python zoo.py wolf: eat beef gota: eat grass
在上个项目的根目录添加源文件(main.cpp)设计
#include <iostream> #include <boost/python.hpp> using namespace boost::python; int main() { Py_Initialize(); if (!Py_IsInitialized()) { std::cout << "Initialize failed" << std::endl; return -1; } try { object sys_module = import("sys"); str module_directory("."); sys_module.attr("path").attr("insert")(1, module_directory); object module = import("zoo"); module.attr("show")(); } catch (const error_already_set&) { PyErr_Print(); } Py_Finalize(); return 0; }
修改CMakeLists.txt
cmake_minimum_required(VERSION 2.8) project(boost) set(CMAKE_CXX_FLAGS "-Wall -g") ### 此处的动态库名必须和BOOST_PYTHON_MODULE()中定义的保持一致,即最后生成的库必须名为boost.so file(GLOB SRC "src/*.cpp") add_library(boost SHARED ${SRC}) set_target_properties(boost PROPERTIES PREFIX "") add_executable(core main.cpp) #dependencies INCLUDE(FindPkgConfig) pkg_check_modules(PYTHON REQUIRED python) include_directories(include /usr/local/include ${PYTHON_INCLUDE_DIRS}) link_directories(/usr/local/lib ${PYTHON_LIBRARY_DIRS}) target_link_libraries(boost boost_python) target_link_libraries(core boost ${PYTHON_LIBRARIES})
编译并执行测试
# cd build # cmake .. # make # ./core wolf: eat beef gota: eat grass
考虑这样一个需求,咱们要展现一个动物园中的动物,可是动物的种类和个数都不固定,这就致使咱们动物园的show
方法须要常常变更,有什么办法能够避免程序的反复编译呢?一种方式就是使用配置文件,将须要展现的动物写入配置文件,而后动物园的show
方法经过解析配置文件来生成须要展现的内容;另外一种方式就是经过Python脚原本实现,由于Python脚本不须要编译,相比于配置文件的方式,Python脚本的方式不须要设计配置文件格式,也不须要实现复杂的解析逻辑,使用起来更加灵活。
在上面的例子中,咱们使用Python脚本实现了本来应该在main.cpp
中实现的show
方法,而后在main.cpp
中调用它,后面若是有改动咱们直接修改Python脚本便可,无需重编程序。