Reputation: 94
I have a raw binary file which I'm trying to cast/move into a ctypes structure I've made, but I can't seem to find the right command to do it.
Simplified version of my code:
class Example_Structure(Structure):
_fields_ = [
("a", c_uint16),
("b", c_uint16, 14),
("c", c_uint16, 2),
("d", c_uint16)
]
#reading a file using open() and getting file size
buf = create_string_buffer(file_size)
file_object.readinto(buf)
struct = Example_Structure()
memmove(addressof(struct),buf,48) #This is the line I'm unsure about
# Maybe use cast(buf,struct) ?
print(struct.a)
I usually get "ArgumentError: argument 1: <type 'exceptions.TypeError'>: wrong type"
on the memmove
line when trying this without addressof(struct)
, but using addressof
just gives me 0
for every field.
Thanks for your help
EDIT: I've found some success using this:
tmp = cast(addressof(buf),POINTER(struct)).contents
Upvotes: 1
Views: 568
Reputation: 177715
It's easier than you think. ctypes.Structure
supports the buffer protocol, so you can directly do:
buf = Example_Structure()
file_object.readinto(buf)
Example:
from ctypes import *
class Example_Structure(Structure):
_fields_ = [
("a", c_uint16),
("b", c_uint16, 14),
("c", c_uint16, 2),
("d", c_uint16)
]
# Create some raw test data
with open('test.bin','wb') as f:
f.write(b'\x22\x33\xff\x7f\xaa\x55')
buf = Example_Structure()
with open('test.bin','rb') as file_object:
file_object.readinto(buf) # Will read sizeof(buf) bytes from file
print(f'{buf.a:04x} {buf.b:04x} {buf.c:04x} {buf.d:04x}')
Output:
3322 3fff 0001 55aa
Upvotes: 0
Reputation: 5805
I think the size of your Structure should be 64. But you don't even have to guess. Use sizeof
so your memmove statement becomes
memmove(addressof(struct),buf,sizeof(struct))
The nice feature of this is that if you make a change to the fields in Example_Structure, you don't have to go back and compute the size.
Finally, I'd recommend you rename your variable from struct to something else. If you ever decide to use the popular struct module that is built into the standard library, you could get into trouble with naming collisions.
Upvotes: 1