ctypes: Get full contents of character array

O

overdrigzed

Hello!

I wanted to get the full contents of a character array stored in a
struct, i.e.
_fields_ = [...("array", c_char * 12)...]
however, ctypes seems to try to return struct.array as a Python string
rather than a character array, and stops as soon as it encounters a
null within the character array.

I ended up having to define a dummy struct
class dummystruct(Structure):
_fields_ = []

and declare array as:
("array", dummystruct)

then use string_at(byref(struct.array), 12).

Is this really the best way of doing it? Is there no better way to
work around ctypes 'guess what you want' behaviour?

Thanks in advance,
Rodrigo
 
A

Aaron \Castironpi\ Brady

Hello!

I wanted to get the full contents of a character array stored in a
struct, i.e.
_fields_ = [...("array", c_char * 12)...]
however, ctypes seems to try to return struct.array as a Python string
rather than a character array, and stops as soon as it encounters a
null within the character array.

I ended up having to define a dummy struct
class dummystruct(Structure):
    _fields_ = []

and declare array as:
("array", dummystruct)

then use string_at(byref(struct.array), 12).

Is this really the best way of doing it? Is there no better way to
work around ctypes 'guess what you want' behaviour?

Thanks in advance,
Rodrigo

Rodrigo,

If you have the option to change your declaration to c_byte* 12, you
have more options. This example prints the null character you wanted.

from ctypes import *
import struct
class S( Structure ):
_fields_= [
( 'array', c_byte* 12 )
]
s= S()

#initialize
struct.pack_into( '7s', s.array, 0, 'abc\x00def' )

#prototype and call PyString_FromStringAndSize
prototype= PYFUNCTYPE( py_object, POINTER( c_byte ), c_size_t )
PyString_FromStringAndSize= prototype( ( "PyString_FromStringAndSize",
pythonapi ) )
x= PyString_FromStringAndSize( s.array, 12 )
print repr( x )

#prototype and call PyString_FromString for contrast
prototype= PYFUNCTYPE( py_object, POINTER( c_byte ) )
PyString_FromString= prototype( ( "PyString_FromString", pythonapi ) )
x= PyString_FromString( s.array )
print repr( x )

/Output:

'abc\x00def\x00\x00\x00\x00\x00'
'abc'
 
O

overdrigzed

I wanted to get the full contents of a character array stored in a
struct, i.e.
_fields_ = [...("array", c_char * 12)...]
however,ctypesseems to try to return struct.array as a Python string
rather than a character array, and stops as soon as it encounters a
null within the character array.
I ended up having to define a dummy struct
class dummystruct(Structure):
    _fields_ = []
and declare array as:
("array", dummystruct)
then use string_at(byref(struct.array), 12).
Is this really the best way of doing it? Is there no better way to
work aroundctypes'guess what you want' behaviour?
Thanks in advance,
Rodrigo

Rodrigo,

If you have the option to change your declaration to c_byte* 12, you
have more options.  This example prints the null character you wanted.

fromctypesimport *
import struct
class S( Structure ):
    _fields_= [
        ( 'array', c_byte* 12 )
    ]
s= S()

#initialize
struct.pack_into( '7s', s.array, 0, 'abc\x00def' )

#prototype and call PyString_FromStringAndSize
prototype= PYFUNCTYPE( py_object, POINTER( c_byte ), c_size_t )
PyString_FromStringAndSize= prototype( ( "PyString_FromStringAndSize",
pythonapi ) )
x= PyString_FromStringAndSize( s.array, 12 )
print repr( x )

#prototype and call PyString_FromString for contrast
prototype= PYFUNCTYPE( py_object, POINTER( c_byte ) )
PyString_FromString= prototype( ( "PyString_FromString", pythonapi ) )
x= PyString_FromString( s.array )
print repr( x )

/Output:

'abc\x00def\x00\x00\x00\x00\x00'
'abc'

Great - and thank you for replying so fast! I found that [chr(x) for x
in struct.array] with array as a c_byte * 12 did what I needed.
 

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

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,736
Latest member
AdolphBig6

Latest Threads

Top