[C++-sig] Re: will custom lvalue converters be supported?
Jonathan Brandmeyer
jbrandmeyer at earthlink.net
Thu Jul 22 00:05:34 CEST 2004
On Wed, 2004-07-21 at 11:14, Igor Lapshin wrote:
> Hi Ralf and Dave,
>
> Thanks for the fast response.
>
> That's exactly the case: there are already hundreds of functions
> written with that "write-back" requirement long before we decided to use
> Python and it seems to me that writing thin wrappers for all of them is
> quite problematic. Moreover, the new functions are still being
> written...
>
> The classes, which are used as parameters for those functions, derived
> from stl::vector, but have additional member-functions, which I cannot
> remove without affecting hundreds of already written functions. Those
> additional members are used only internally and not from Python, thus
> tuple or sequence functionality is sufficient.
[snip]
>
> Is there any way to write a generic thin wrapper supporting "write back"
> for various functions with different signatures but with very limited
> set of types (we have some 5 types)?
Sure. Here is something. Hopefully, it can be generalized/specialized
as needed for your requirements, and isn't too non-portable (er, it
works with gcc 3.3.4 and 3.4.1 ...). It takes advantage of the idea
that the function pointers passed to class_<T>::def() can be free
functions that take a T pointer or reference as their first argument.
If you have no choice but to go the route of wrapping the type to be
list-like, I would recommend the vector_indexing_suite<>. (as a side
note, it supports basic slicing, but not extended slicing of the wrapped
type).
-Jonathan
---------------- A somewhat generic thin wrapper ---------------------
#include <vector>
#include <boost/python.hpp>
using namespace boost::python;
template <typename T, void (T:: *T_fn)(std::vector<double>&)>
void
call_from_python_with_list( T* This, boost::python::list py_arg1)
{
int arg1_size = extract<int>(py_arg1.attr("__len__")());
std::vector<double> cpp_arg1(arg1_size);
// Initialize cpp_arg1 from py_arg1
for (int i = 0; i < arg1_size; ++i)
cpp_arg1[i] = extract<double>(py_arg1[i]);
// Call the C++ mem fun that takes an lvalue.
(This->*T_fn)( cpp_arg1);
// overwrite py_arg1 with data from cpp_arg1
py_arg1.attr("__delslice__")(0, arg1_size);
for (std::vector<double>::iterator i = cpp_arg1.begin();
i < cpp_arg1.end(); ++i)
py_arg1.append( object(*i));
return;
}
struct call_me
{
void f( std::vector<double>& arg)
{
// do something to modify the vector.
arg.push_back(2);
}
};
BOOST_PYTHON_MODULE(call_from_python_with_list)
{
class_<call_me>("call_me")
.def( "f", &call_from_python_with_list< call_me, &call_me::f>)
;
}
More information about the Cplusplus-sig
mailing list