A little comments of ctypes and construct.

Ò

Ò»Ê×Ê«

Hi all,

Recently I asked a question on this group:


I got these suggestion:

1) try construct

2) try ctypes

----------------

I spend half a day on construct and here's my conclusion:

1. It really good for parse(unpack) data structures.

But

1. It's not that good for pack.
2. From the documents and example, can not find out how to describe
nested struct array.

for example:

typedef struct _Point
{
int x;
int y;
} Point;

typedef struct _Shape
{
int z;
Point ap[2];
}Shape;

Can not find out how to describe this..


----------------

Then I tried ctypes.

1. It works fine for pack

BUT:

1. I can not figure out how to unpack. The examples I googled doesn't
work on my computer.

http://markmail.org/message/44tu6rm4nejxgbdd

2. BigEndianStructure can not be nested. So. If you need bid endian,
you got bad luck.

So, both of them are not ideal solution to pack and unpack
sophisticated C style data structures.

----------------

BTW: Some one suggested that I should use struct.Struct and
namedtuple.

I skimmed the document, but can't find a clear way to handle nested
structures.
 
A

Aaron Brady

Hi all,

Recently I asked a question on this group:
snip

typedef struct _Point
{
int x;
int y;

} Point;

typedef struct _Shape
{
int z;
Point ap[2];

}Shape; snip
2. BigEndianStructure can not be nested. So. If you need bid endian,
you got bad luck.

A bug is filed about this.

I have this code working:

import ctypes as c
class Point( c.LittleEndianStructure ):
_fields_= [
( 'x', c.c_int ),
( 'y', c.c_int )
]

class Shape( c.LittleEndianStructure ):
_fields_= [
( 'z', c.c_int ),
( 'ap', Point* 2 )
]

lib= c.WinDLL( 'ng36ext.pyd' )
lib.make.argtypes= [ ]
lib.make.restype= Shape
shape= lib.make( )
print shape.z, shape.ap[0].x, shape.ap[0].y, shape.ap[1].x, shape.ap
[1].y

/Output:

10 20 30 40 50
20
10 20 30 40 50

/Definition for 'make':

Shape make( void ) {
Shape shape;
shape.z= 10;
shape.ap[ 0 ].x= 20;
shape.ap[ 0 ].y= 30;
shape.ap[ 1 ].x= 40;
shape.ap[ 1 ].y= 50;
printf( "%i %i %i %i %i\n", shape.z, shape.ap[0].x, shape.ap[0].y,
shape.ap[1].x, shape.ap[1].y );
printf( "%i\n", sizeof( shape ) );
return shape;
}

What is your next step?
 
Ò

Ò»Ê×Ê«

I didn't try your code. That might be working since it a completely
different method.

What mean is

pack works:
=========================
class POINT(Structure):

_fields_ = [('x', c_int), ('y', c_int)]

p = POINT(1,2) p.x, p.y (1, 2) str(buffer(p))
s = str(buffer(p))
=========================

unpack doesn't
=========================
p2 = POINT() ctypes.memmove(p2, s, ctypes.sizeof(POINT)) 14688904
p2.x, p2.y
=========================

I am not trying to parse data generated by a dll, but data received
from network.
That's also why I need Big Endian.

Recently I asked a question on this group: snip

typedef struct _Point
{
int x;
int y;
typedef struct _Shape
{
int z;
Point ap[2];
snip
2. BigEndianStructure can not be nested. So. If you need bid endian,
you got bad luck.

A bug is filed about this.

I have this code working:

import ctypes as c
class Point( c.LittleEndianStructure ):
_fields_= [
( 'x', c.c_int ),
( 'y', c.c_int )
]

class Shape( c.LittleEndianStructure ):
_fields_= [
( 'z', c.c_int ),
( 'ap', Point* 2 )
]

lib= c.WinDLL( 'ng36ext.pyd' )
lib.make.argtypes= [ ]
lib.make.restype= Shape
shape= lib.make( )
print shape.z, shape.ap[0].x, shape.ap[0].y, shape.ap[1].x, shape.ap
[1].y

/Output:

10 20 30 40 50
20
10 20 30 40 50

/Definition for 'make':

Shape make( void ) {
Shape shape;
shape.z= 10;
shape.ap[ 0 ].x= 20;
shape.ap[ 0 ].y= 30;
shape.ap[ 1 ].x= 40;
shape.ap[ 1 ].y= 50;
printf( "%i %i %i %i %i\n", shape.z, shape.ap[0].x, shape.ap[0].y,
shape.ap[1].x, shape.ap[1].y );
printf( "%i\n", sizeof( shape ) );
return shape;

}

What is your next step?
 
Ò

Ò»Ê×Ê«

OK, I was wrong with construct!

I wrote to the author and he replied. It works!

I am really glad there IS a easy way to handle binary data in python.
.... SNInt32("x"), # Signed, Native byte-order, Int 32 bits
('int' is platform specific, so your int may be different)
.... SNInt32("y"),
.... ).... SNInt32("z"),
.... Rename("ap", # without the Rename field, the name would be
"point" (Arrays inherit their name from their element)
.... Array(2, point)
.... ),
.... )Container:
z = 2054847098
ap = [
Container:
x = 2021161080
y = 2038004089
Container:
x = 1482184792
y = 1499027801
]
 

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,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top