C++パッケージpythonインタフェース(libboost-python)

8179 ワード

サマリ
Pythonテクノロジードキュメントでは、PythonとC++の間で相互に呼び出される部分を見つけることができます.それぞれextendingとEmbeddingと呼ばれています.技術文書Extending and Embedding the Python Interpreterを参照してください.同時に、Python/C APIインタフェースPython/C API Reference Manualも提供される.簡単な呼び出しでは便利ですが、複雑な構造、パッケージ、継承では操作が複雑です.そこで、プロジェクトでlibboost-pythonを使用してC++をカプセル化したPythonインタフェースの心得を紹介します.libboost-pythonはC++のすべてのパッケージを満たすことができます.
CMake構成
FIND_PACKAGE(Boost 1.59.0) IF(Boost_FOUND) include_directories(${Boost_INCLUDE_DIRS} ../venv/local/include/python2.7/) SET(Boost_USE_STATIC_LIBS OFF) SET(Boost_USE_MULTITHREADED ON) SET(Boost_USE_STATIC_RUNTIME OFF) FIND_PACKAGE(Boost 1.59.0 COMPONENTS python) ADD_LIBRARY(pyfaceos SHARED main.cpp faceos.cpp) target_link_libraries(pyfaceos -ldl ${Boost_LIBRARIES}) set_target_properties(pyfaceos PROPERTIES PREFIX “” OUTPUT_NAME “faceos”) ELSEIF(NOT Boost_FOUND) MESSAGE(FATAL_ERROR “Unable to find correct Boost version. Did you set BOOST_ROOT?”) ENDIF()
宣言ライブラリの名前
BOOST_PYTHON_MODULE(lib name)
{
}

タイプマッピング
enum
enum_("Color")
        .value("RED",RED)
        .value("BLUE",BLUE)
        .value("GREEN",GREEN)
        .export_values();

class/struct
class_("rect")
        .def_readwrite("left",  &cv_rect_t::left)
        .def_readwrite("top",   &cv_rect_t::top)
        .def_readwrite("right", &cv_rect_t::right)
        .def_readwrite("bottom",&cv_rect_t::bottom)
        .def("somefunc", &rect::somefunc) ;

パラメータに参照が存在し、参照間または戻り値との間に相互関係がある場合は、呼び出しポリシーを追加する必要があります.
パッヶージようき
//        
void IndexError() { PyErr_SetString(PyExc_IndexError, "Index out of range"); }

template<class T>
struct std_item
{
    typedef typename T::value_type V;
    static V& get(T & x, int i)
    {
        if( i<0 ) i+=x.size();
        if( i>=0 && i//printf("in size
"); return x[i]; } IndexError(); } static void set(T & x, int i, V const& v) { if( i<0 ) i+=x.size(); if( i>=0 && ielse IndexError(); } static void del(T & x, int i) { if( i<0 ) i+=x.size(); if( i>=0 && ielse IndexError(); } static void add(T & x, V const& v) { x.push_back(v); } }; // typedef vector VecClass; // class_("VecClass") .def("__len__", &VecClass::size) .def("clear", &VecClass::clear) .def("append", &std_item::add, with_custodian_and_ward<1,2>()) // to let container keep value .def("__getitem__", &std_item::get, return_value_policy()) .def("__setitem__", &std_item::set, with_custodian_and_ward<1,2>()) // to let container keep value .def("__delitem__", &std_item::del);

同様に,この方法を用いて配列,list,mapなどをカプセル化することができる.
ドッキング
ピットは以前の仕事の中で、私は1つのndarrayパラメータをC++関数の中に伝えたいと思って、前にnumericを使ってC++の中に入って、num_を利用しますutilはデータコンテンツを取得します.このライブラリは、最下位のPython C APIのパッケージですが、使いにくいです.
numericおよびboost-pythonを使用してpythonオブジェクトをカプセル化するだけで、データの転送と取得が完了します.
ここではndarrayの伝達に重点を置き、referrence mannulのObject Wrappersセクションを参照してください.
//  ndarray    ,    
bp::str s = img.tostring();
char* c_str = bp::extract<char*>(s);
//    
const bp::tuple &shape = bp::extract<:tuple>(img.attr("shape"));
int dims = bp::extract<int>(shape.attr("__len__")());
int height = bp::extract<int>(shape[0]);
int width = bp::extract<int>(shape[1]);
//      
#include 
#include 

// sets the first element in a 2d numeric array
void set_first_element(numeric::array& y, double value)
{
    y[make_tuple(0,0)] = value;
}

http://www.boost.org/doc/libs/1_61_0/libs/python/doc/html/tutorial/index.html http://www.boost.org/doc/libs/1_61_0/libs/python/doc/html/