logo       

Re: long long unsigned issue...: msg#00321

python.c++

Subject: Re: long long unsigned issue...

"David Abrahams" <dave@xxxxxxxxxxxxxxxxxxxx> wrote in message
news:ud6i4xtz2.fsf@xxxxxxxxxxxxxxxxxxxxxxx
> David Abrahams <dave@xxxxxxxxxxxxxxxxxxxx> writes:
>
> One more note about this stuff: you have so many constructors and so
> much potential for ambiguity it's hard to make sense of what you're
> actually trying to achieve. Maybe if you could say a little more
> about that it would be easier to help you.
>
> --
> Dave Abrahams
> Boost Consulting
> www.boost-consulting.com

The C++ library that I am wrapping is part of a testbench library for
verification of
RTL designs of ASICs. The library has bit vector signal (to connect to rtl
signals)
classes, concurrency classes, randomization classes etc. Supporting scripting
in the verification environment is going to be a great productivity booster, I
think.
And hence the attempt to use boost python.

I used pyste (thanks to Nicodemus) to jump start the wrapping process. I have a
use case model in mind that I am hand crafting the wrappers to now.

Looking at just the signal class, it has constructors for
a) Constructing signals of given width eg. signal(23,0) -- a 24 bit signal,
signal(23,0, 0xffffff) -- a 24 bit signal with value 0xffffff,
b) Constructors for constants eg. signal(0x00ffffff) -- 24 bit signal, etc.
c) Constructors from character representation, long long, long, and
int representations of numbers.
d) copy, default etc.

Other requirements of python signal class are:
a) handling 4state: bits can be 0, 1, X or Z.
b) slice set and get ie. sig[18:4] = 2; sig[:] = 4;
c) ability to convert from and to python long.

Anyway the above was a little introduction to
the big picture at my end.

Coming to issue with long_ conversion that I have had.
I constructed a toy example to experiment with the long_
conversion issue. Recapping, given the class

class Y {
public:
Y() : y(0L) { }
Y(int y) : y(y) { }
Y(long long unsigned int y) : y(y) { }
Y(int s, const Y & y) : y(y << s) { }
Y(Y const& rhs) : y(rhs.y) { }
virtual ~Y() { }

operator int() const { return y; }

void operator=(Y const& y) {
this->y = y.y;
}

long long unsigned int y;
};

that I would like to wrap to python:

BOOST_PYTHON_MODULE(hello)
{
class_< Y, Y_Wrapper >("Y", init< >())
.def(init< const Y & >())
.def(init< int, const Y & >())
.def(init< int >())
.def(init< long long unsigned int >())
.def_readwrite("y", &Y::y)
.def("__int__", &Y::operator int)
;
impilcitly_convertible<int, Y>();
}

The implicitly_converitble above is to facilitate conversion
to Y(int, &Y) for python x = hello.Y(2, 24) etc.
I wanted to add conversion capability from and to python
long_ which was possible via a wrapper class (again, something
that pyste originally generated):

namespace {
struct Y_Wrapper: Y {
Y_Wrapper (PyObject* self_) : Y(), self(self_) {}
Y_Wrapper (PyObject* self_, int y) : Y(y), self(self_) {}
Y_Wrapper (PyObject* self_, long long unsigned int y) : Y(y), self(self_)
{}
Y_Wrapper (PyObject* self_, int s, const Y& y) : Y(s,y), self(self_) {}
Y_Wrapper (PyObject* self_, const Y& y) : Y(y), self(self_) {}
Y_Wrapper (PyObject* self_, boost::python::long_ y) : Y(0), self(self_)
{printf("hello
long_");}

PyObject* self;
};
}

and adding

.def(init< long_ >())

to module definition.

So far so good. With your recent fixes it works perfectly for python
construction
of Y from long eg. x = hello.Y(4294967295) -- this is the type b constructor
in the
constructors I enumerated above. But if I want to construct signals of given
width,
then I would have x = signal(127,0, 4294967295), or x = hello.Y(127, 4294967295)
for the toy example. This statement will cause a runtime exception fault
saying that "OverflowError: long int too large to convert to int", probably
because it
is trying construct to Y(int s, const Y& y) and does not know how to make long_
to Y! My question here was :

Now that we have a long_ to Y_Wrapper constructor
and that class_ Y has Y_Wrapper as one of the bases, is it possible to use an
implicity_convertible<long_, Y_Wrapper>(); to be able to facilitate the
conversion?

I am not comletely dead in water:
I have added a .def(init<int, long_>) to module definition and a
Y_Wrapper(PyObject* self_, int s, boost::python::long_ y)
to Y_Wrapper to get around the inability to do a
implicitly_convertible<long_ Y_Wrapper>() to effect the conversion.
This works for me right now. I once again thank you for helping me
with the issue I had.

If you have read so far, I had some more observations as a user:

Some of the use case scenarios for boost python are:

a) Expose C++ classes as python classes alone. User will not derive
from the exposed classes.
b) Expose C++ classes as derivable classes in python.
c) Embedded scenarios with above two where it goes c++ to python to c++
back etc.
d) Expose C++ classes as derived or as convertible to python types (numeric,
tuples, str etc.)

My particular use case is a) and d). And there is adequate
documentation/information to be able to be able to figure it out but it is
difficult. Perhaps the document can handle c) and d) a little more?
Anything I can help with?

Thanks again,
Milind


<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

News | FAQ | advertise