Re: tbufferfile in pyroot

From: Andy Mastbaum <mastbaum_at_hep.upenn.edu>
Date: Mon, 14 Nov 2011 11:57:15 -0500


Wim,

Thanks for the quick reply!

After some further hacking, it turns out the source of my troubles was trying to pass a string containing null characters into C. It seems the C interface makes null-terminated C strings out of unterminated Python strings by stopping at the first zero. Fine for "hello, world!", but a real gotcha for buffers!

I got it working by passing in an array instead, which PyROOT casts as a null pointer automatically:

     msg = socket.recv(copy=False)
     b = array.array('c', msg.bytes)
     buf = ROOT.TBufferFile(ROOT.TBuffer.kRead, len(b), b, False, 0)
     h = buf.ReadObject(ROOT.TH1F.Class()) # works!

(Incidentally, it's odd that the TBuffer constructor takes the buffer as a null pointer... a char* seems a more sensible choice since it has to be a byte sequence.)

Best,
Andy

On 11/14/2011 01:59 AM, wlavrijsen_at_lbl.gov wrote:
> Andy,
>
>> msg = socket.recv(copy=False)
>> buf = ROOT.TBufferFile(ROOT.TBuffer.kRead, len(msg.buffer),
>> sip.voidptr(id(msg.buffer)).ascobject(), False)
>> o = id(buf.ReadObjectAny(ROOT.TH1F.Class())) # error!
>>
>> I use SIP for casting, since I believe that's what PyROOT is written with
>
> it's not: PyROOT is based on CINT dictionaries. Are you sure btw. that the
> result of id() will yield a pointer to the underlying object for
> msg.buffer?
> It normally (and only in CPython) is a pointer to the python object; it
> will
> not work for PyROOT objects for sure (use ROOT.AsCObject() instead and pass
> that result around for those cases, but I don't know what socket returns).
>
> Best regards,
> Wim
Received on Mon Nov 14 2011 - 18:02:43 CET

This archive was generated by hypermail 2.2.0 : Mon Nov 14 2011 - 23:50:02 CET