ctypes initializer

C

castironpi

Is there a way to initialize a ctypes Structure to point to an offset
into a buffer? I don't know if the way I'm doing it is supported.
 
M

marek.rocki

castironpi napisa³(a):
Is there a way to initialize a ctypes Structure to point to an offset
into a buffer? I don't know if the way I'm doing it is supported.

There is a high probability you're abusing ctypes too much, but it's
possible. The following seems to work:

from ctypes import *

class S(Structure):
_fields_ = [('x', c_uint), ('y', c_int)]
rawdata = create_string_buffer('\xEE\xFF\x78\x56\x34\x12\xFF\xFF\xFF
\xFF\xAA')

# Try to make a structure s of type S which takes its data from
rawdata
# buffer, starting at index 2
s = cast(c_void_p(addressof(rawdata)+2), POINTER(S)).contents

print hex(s.x), s.y # Should be 12345678h and -1
 
C

castironpi

castironpi napisa³(a):
Is there a way to initialize a ctypes Structure to point to an offset
into a buffer? I don't know if the way I'm doing it is supported.

There is a high probability you're abusing ctypes too much, but it's
possible. The following seems to work:

from ctypes import *

class S(Structure):
        _fields_ = [('x', c_uint), ('y', c_int)]
rawdata = create_string_buffer('\xEE\xFF\x78\x56\x34\x12\xFF\xFF\xFF
\xFF\xAA')

# Try to make a structure s of type S which takes its data from
rawdata
# buffer, starting at index 2
s = cast(c_void_p(addressof(rawdata)+2), POINTER(S)).contents

print hex(s.x), s.y # Should be 12345678h and -1

Output is 0x12345678L -1, as you state. I understand that '\xEE\xFF'
is skipped with addressof(rawdata)+ 2, which makes +2 an offset into
the buffer.

At this point, I'd say the use of 'cast' is dubious, but possible to
support. My problem comes in, in that the buffer I have comes from a
non-ctypes source. It is a, <drumroll please> mmap.

My goals in exploring this are persistence and IPC, which are
certainly not abusing Python too much. 'ctypes' may not be right for
the job though. The solution I looked at got even worse than 'from
_ctypes import _cast_addr'. I want a supported way to do it.
 
C

castironpi

castironpi napisa³(a):
There is a high probability you're abusing ctypes too much, but it's
possible. The following seems to work:
from ctypes import *
class S(Structure):
        _fields_ = [('x', c_uint), ('y', c_int)]
rawdata = create_string_buffer('\xEE\xFF\x78\x56\x34\x12\xFF\xFF\xFF
\xFF\xAA')
# Try to make a structure s of type S which takes its data from
rawdata
# buffer, starting at index 2
s = cast(c_void_p(addressof(rawdata)+2), POINTER(S)).contents
print hex(s.x), s.y # Should be 12345678h and -1

Output is 0x12345678L -1, as you state.  I understand that '\xEE\xFF'
is skipped with addressof(rawdata)+ 2, which makes +2 an offset into
the buffer.

At this point, I'd say the use of 'cast' is dubious, but possible to
support.  My problem comes in, in that the buffer I have comes from a
non-ctypes source.  It is a, <drumroll please> mmap.

My goals in exploring this are persistence and IPC, which are
certainly not abusing Python too much.  'ctypes' may not be right for
the job though.  The solution I looked at got even worse than 'from
_ctypes import _cast_addr'.  I want a supported way to do it.

The solution could be as simple as returning a ctypes pointer from an
mmap method. Does this require a PEP, or ought a patch to do it?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,792
Messages
2,569,639
Members
45,351
Latest member
RoxiePulli

Latest Threads

Top