ctypes: buffers and memoryviews

Stephen <[email protected]> Fri, 05 Jul 2013 23:10:27 +1000
Newsgroups gmane.comp.python.ctypes
Message-ID <[email protected]>

Debian 3.9.6-1 x86_64 GNU/Linux

Python 3.2.4 (default, May  8 2013, 20:55:18)
[GCC 4.7.3] on linux2
 >>> import ctypes
 >>> ctypes.__version__
'1.1.0'


Hello,

In python 2.x I would use ctypes to create a structure and write a 
buffer for transmission of a message.

I would use a recipe I found online that followed the format

class CMD_HEADER(ctypes.Structure):
     _pack_ = 2
     _fields_ = [ ('command', ctypes.c_ushort ),
                  ('length',   ctypes.c_uint   )
                  ]

     def CreateTxBuffer(self):
         return buffer(self)[:]

     def receiveSome(self, bytes):
         fit = min(len(bytes), ctypes.sizeof(self))
         ctypes.memmove(ctypes.addressof(self), bytes, fit)

This has worked for me well.

Now python3 has removed buffer, and seems I should use memoryview instead
I can't seem to find a python 3 recipe online to achieve the same so I 
came up with the following modification to CreateTxBuffer

     def CreateTxBuffer(self):
         return memoryview(self)

Seems to work on surface, but I'm having all sorts of trouble using the 
resultant memoryview.

for the following sample program

import ctypes
from binascii import hexlify

class CMD_HEADER(ctypes.Structure):
     _pack_ = 2
     _fields_ = [ ('command', ctypes.c_ushort ),
                  ('length',   ctypes.c_uint   )
                  ]
     def CreateTxBuffer(self):
         return memoryview(self)

     def receiveSome(self, bytes):
         fit = min(len(bytes), ctypes.sizeof(self))
         ctypes.memmove(ctypes.addressof(self), bytes, fit)

# create a ctype struct and populate it with data
msg = CMD_HEADER()
msg.command = 0x123
msg.length=2

# Get access to the underlying message structure data (should be a 
memory view)
txbuf = msg.CreateTxBuffer()

#create a bytearry with same data then create memoryview to that byte array
bb = bytearray( txbuf )
mv = memoryview(bb)

print("type={0} , len={1} , shape={2}, buf={3}".format(type(txbuf), 
len(txbuf), txbuf.shape, hexlify(txbuf)) )
print("type={0} , len={1} , shape={2}, buf={3}".format(type(mv), 
len(mv), mv.shape, hexlify(mv)) )



I get the following output, indicating the memory view I get from ctypes 
is behaving differently than what I thought it should.
type=<class 'memoryview'> , len=1 , shape=None, buf=b'230102000000'
type=<class 'memoryview'> , len=6 , shape=(6,), buf=b'230102000000'

Notice the 'ctypes' memoryview I dont have correct len or shape

I'm getting out of my depth here, not really sure what I've done wrong.
So I'd like to ask is there a correct way to create the tx buffer in 
python 3, obviously my method is not correct.


Thanks
Steve

------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev