By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,079 Members | 927 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,079 IT Pros & Developers. It's quick & easy.

Interconvert a ctypes.Structure to/from a binary string?

P: n/a
Basically, I'd like to use the ctypes module as a much more descriptive
"struct" module.

Is there a way to take a ctypes.Structure-based class and convert it
to/from a binary string?

Thanks,
-a
Aug 2 '08 #1
Share this Question
Share on Google+
3 Replies


P: n/a
On 2 Aug., 08:35, Andrew Lentvorski <bs...@allcaps.orgwrote:
Basically, I'd like to use the ctypes module as a much more descriptive
"struct" module.

Is there a way to take a ctypes.Structure-based class and convert it
to/from a binary string?

Thanks,
-a
My first idea was :

from ctypes import *
from pickle import *

class T(Structure): pass

print dumps(T())

which raises an TypeError, "abstract class".

And then I found

http://osdir.com/ml/python.ctypes/2006-03/msg00009.html

Greetings, Uwe

Aug 2 '08 #2

P: n/a
On Aug 1, 11:35 pm, Andrew Lentvorski <bs...@allcaps.orgwrote:
Basically, I'd like to use the ctypes module as a much more descriptive
"struct" module.

Is there a way to take a ctypes.Structure-based class and convert it
to/from a binary string?

Thanks,
-a
After chugging through the ctypes source code, I found that I can
abuse ctypes into doing what I want.

Here is how I did it. I can abuse
string_at(addressof(SomeCtypesClass), length) to get a binary string
out of ctypes while I use:

def analyze_elf_header(binaryData):
headerSize = ctypes.sizeof(Elf32_Ehdr)
header = Elf32_Ehdr()

# Abuse ctypes to initialize from a string
bb = ctypes.create_string_buffer(binaryData[0:headerSize])
ctypes.memmove(ctypes.addressof(header), ctypes.addressof(bb),
headerSize)

To jam stuff into a ctypes class. This seems like an oversight in the
module though. It would really be better if the class itself had
methods to init from/produce to a binary string.

However, I would prefer that somebody who actually knows ctypes to
weigh in here with comments about what I did.

Thanks,
-a
Aug 2 '08 #3

P: n/a
Andrew P. Lentvorski, Jr. <bs****@gmail.comwrote:
On Aug 1, 11:35 pm, Andrew Lentvorski <bs...@allcaps.orgwrote:
Basically, I'd like to use the ctypes module as a much more descriptive
"struct" module.

Is there a way to take a ctypes.Structure-based class and convert it
to/from a binary string?

Thanks,
-a

After chugging through the ctypes source code, I found that I can
abuse ctypes into doing what I want.

Here is how I did it. I can abuse
string_at(addressof(SomeCtypesClass), length) to get a binary string
out of ctypes while I use:

def analyze_elf_header(binaryData):
headerSize = ctypes.sizeof(Elf32_Ehdr)
header = Elf32_Ehdr()

# Abuse ctypes to initialize from a string
bb = ctypes.create_string_buffer(binaryData[0:headerSize])
ctypes.memmove(ctypes.addressof(header), ctypes.addressof(bb),
headerSize)

To jam stuff into a ctypes class. This seems like an oversight in the
module though. It would really be better if the class itself had
methods to init from/produce to a binary string.

However, I would prefer that somebody who actually knows ctypes to
weigh in here with comments about what I did.
I have found myself doing this quite a bit with ctypes. It is common
to get a block of data in which represents a stream of structures
which have to be unpicked and made into ctypes structs before use.
Making that stream is an equal challenge.

I've found a couple of ways of doing it.

Setup
>>from ctypes import *
class A(Structure):
... _fields_ = [("x", c_int)]
...
>>packet="\x02\x01\x00\x00"
Eg to make a struct from a string
>>a = cast(packet, POINTER(A)).contents
a.x
258
>>>
Or (this is identical to your method)
>>a = A()
a.x
0
>>memmove(addressof(a), packet, sizeof(a))
3083811008L
>>a.x
258

I think the second of those methods is promoted by the ctypes
documentation. I'm not sure about the lifetimes of the .contents in
the first method!

And the reverse
>>string_at(addressof(a), sizeof(a))
'\x02\x01\x00\x00'
>>>
Which I think is probably acceptable...

Some to/from binary methods would be nice, or failing that an explicit
section in the docs!

--
Nick Craig-Wood <ni**@craig-wood.com-- http://www.craig-wood.com/nick
Aug 4 '08 #4

This discussion thread is closed

Replies have been disabled for this discussion.