Thursday, September 15, 2016

boost-python wrapping. accessing to numpy array example

This is a example for boost-python, especially about numpy array.
The codes are about CMakeLists.txt, hello.py, hello.cpp file.
 --------------------------------------------------------------------------
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
find_package(PythonLibs REQUIRED)
string(REGEX MATCH "([0-9])\\.*" output ${PYTHONLIBS_VERSION_STRING})
if(${output} EQUAL "2.")
 find_package(Boost COMPONENTS python)
else()
    find_package(Boost COMPONENTS python3)
endif()
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR})
file(GLOB lib_headers "src/*.h")
file(GLOB lib_src "src/*.cpp")
set(prjname hello)
add_library(${prjname} SHARED ${lib_src} ${lib_headers})
set_target_properties(${prjname} PROPERTIES DEBUG_POSTFIX "_d")
if(WIN32)
  set_target_properties(${prjname} PROPERTIES SUFFIX ".pyd")
endif(WIN32)
target_include_directories(${prjname} PUBLIC ${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS})
target_link_libraries(${prjname} ${Boost_LIBRARIES} ${PYTHON_LIBRARIES})
--------------------------------------------------------------------------
 
if __debug__:
 import hello_d as hello
else:
 import hello
import numpy as np

hello.greet()
uv = np.array([[1.0, 2.0]])
print 'uv =', uv
hello.get_set_element(uv, 3.0)
print 'uv0 = ', uv

#include <boost/python.hpp>
#include <boost/python/numeric.hpp>
#include <boost/python/extract.hpp>
#include <boost/python/tuple.hpp>

#ifdef _DEBUG
#define PY_MODULE BOOST_PYTHON_MODULE(hello_d)
#else
#define PY_MODULE BOOST_PYTHON_MODULE(hello)
#endif

char const* greet(){
        return "hello\n";
}

void get_set_element(boost::python::numeric::array& y, double value){
        double d = boost::python::extract<double>(y[boost::python::make_tuple(0, 0)]);
        printf("array[0,0] = %f\n", d);
        y[boost::python::make_tuple(0, 0)] = value;
}

PY_MODULE{
        boost::python::numeric::array::set_module_and_type("numpy", "ndarray");
        boost::python::def("get_set_element", &get_set_element);
        boost::python::def("greet", greet);
}