[C++-sig] how to return arbitrary (python-)objects from boost (solved, kind of...)?

Joerg Kurlbaum jkur at informatik.uni-bremen.de
Thu Apr 24 11:10:10 CEST 2008


On Wed, Apr 23, 2008 at 11:04:10AM -0400, Andreas Klöckner wrote:
> On Mittwoch 23 April 2008, Joerg Kurlbaum wrote:
> > Okay. I've read about converters. But the noddy example isn't very
> > helpful. The problem is, i think, that all the types i want to use are
> > already there. I have the QImage in C++ and in Python. I want to create
> > a QImage in the wrapper code from the image data and return that to the
> > python program.
> 
> Simple issue: PyQt uses sip to wrap Qt into Python. Boost.Python and sip are 
> not on speaking terms. If what you're wrapping involves lots of Qt stuff, sip 
> might be a better choice for a wrapper generator.

Right now there is only QImage involved. I choose Boost::python for it's
clearness and because it is independent of any other tools, that i would
have to include in my toolchain/build system. Writing a python wrapper
in pure C++ is awesome, as long as you don't have to trace errors in all
that template stuff.

But i found a solution for my special problem:

In PyQt4 you can get a sip.voidptr to the scanLines of the QImage (which
is acutally a byte buffer). You can convert this sip.voidptr to an
integer with the Python int() function. Then i wrote  a function that
takes this pointer address and fills the buffer. I have to create the
QImage in Python but that okay for me so far.

Then in Python i write:

cam = Camera() # my wrapped camera class
image = QtGui.QImage(640, 480, Qt.QImage.Format_ARGB32)
# ...
cam.put_image_to_sippointer(int(image.scanLine(0)))


In the boost::python wrapper:

void put_image_to_sippointer(boost::python::object obj)
{
    uint32_t address = extract<uint32_t>(obj);
    uint8_t* line = reinterpret_cast<uint8_t*>(address);
    uint8_t* data = rgbframe->image;
    unsigned char R,G,B,A;
    while ( data < (rgbframe->image + (rgbframe->size[0]*rgbframe->size[1]*3)) )
    {
        R = *data++;
        G = *data++;
        B = *data++;
        A = 255;
        *line++ = B;
        *line++ = G;
        *line++ = R;
        *line++ = A;
    }
}

This is a bit of a hack and i think the idea from Ralf would be much
cleaner, but for now i have a solution that is fast enough and easy to implement.

Thanks for all your answers.

Regards,
    Jörg :-)

-- 
Jörg Kurlbaum (jkur at informatik.uni-bremen.de)           Cartesium 00.056
GPG-ID: CAC40EA9                                        Enrique Schmidt Str. 5
T: 0421/218-64201                                       Universität Bremen
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20080424/0739e2ac/attachment.pgp>


More information about the Cplusplus-sig mailing list