return_pointee_value

Definition

Class return_pointee_value is a model of ResultConverterGenerator which can be used to wrap C++ functions, that return a pointer to a C++ object. The policy implements the following logic:

if( <<<return value is NULL pointer>>> ){
    return None;
}
else{
    return boost::python::object( *<<<return value>>> );
}

The return type of the function should be T*.

It passes the value of the pointee to Python, thus the conversion for T is used. This call policy could be used to return pointers to Python, which types are not known to Boost.Python, but only a conversion for the pointees.

Therefore this policy should be used to return pointers to objects, whose types were wrapped with other tools, such as SWIGSIP.

Another usage of this call policy is to return to Python new object, which contains copy of (*return value).

Please note: This policy does not take ownership of the wrapped pointer. If the object pointed to is deleted in C++, the python-object will become invalid too, if your custom conversion depends on the original object.

Examples

Unknown type

This technique and example was contributed by Maximilian Matthe.

struct int_wrapper{
     int_wrapper(int v)
     : val(v)
     {}

     int val;
};

//we will expose the following function
int_wrapper* return_int_wrapper(){
     static int_wrapper w(42);
     return &w;
}

//the Boost.Python custom converter
struct convert_int_wrapper{
    static PyObject* convert(int_wrapper const& w){
        boost::python::object value(w.val);
        return boost::python::incref( value.ptr() );
    }
};


BOOST_PYTHON_MODULE(my_module){
     using namespace boost::python;
     //register our custom converter
     to_python_converter<int_wrapper, convert_int_wrapper, false>();

     def( "return_int_wrapper"
          , &return_int_wrapper
          , return_value_policy<return_pointee_value>() );
}

Python code:

import my_module

assert 42 == my_module.return_int_wrapper()

Return pointee value

float* get_value(){
    static float value = 0.5;
    return &value;
}

float* get_null_value(){
  return (float*)( 0 );
}

namespace bpl = boost::python;
BOOST_PYTHON_MODULE(my_module){
  def( "get_value"
       , bpl::return_value_policy< pyplusplus::call_policies::return_pointee_value<> >() );

  def( "get_null_value"
       , bpl::return_value_policy< pyplusplus::call_policies::return_pointee_value<> >() );
}

The Py++ code is not that different from what you already know:

from pyplusplus import module_builder
from pyplusplus.module_builder import call_policies

mb = module_builder.module_builder_t( ... )
mb.free_function( return_type='float *' ).call_policies \
    = call_policies.return_value_policy( call_policies.return_pointee_value )

Python code:

import my_module

assert 0.5 == my_module.get_value()
assert None is my_module.get_null_value()