Re: who can tell me the difference in ctypes.sizeof between Ironpython and python in using ctypes to create structure?

eryksun <[email protected]> Wed, 11 Mar 2015 06:19:34 -0500
Newsgroups gmane.comp.python.ctypes
Message-ID <CACL+1asj3ZHZLwY5ZupERZh2zC+PyYwQ-1mmP9AUOJJKGAPNNw@mail.gmail.com>
On Tue, Mar 10, 2015 at 9:49 PM, 狂禅 <[email protected]> wrote:
> recently i meet a problem in using Ironpython.
>     import ctypes as ct
>
>     class Data(ct.LittleEndianStructure):
>         _pack_      = 2
>         _fields_    = [
>
>             ('a',ct.c_ubyte),
>             ('b',ct.c_ubyte),
>             ('c',ct.c_ubyte),
>             ('d',ct.c_ushort),
>             ('e',ct.c_uint),
>             ('f',ct.c_ubyte),
>         ]
>     if __name__ == "__main__":
>         a = Data()
>         print ct.sizeof(a)
> as is show above.when i used this script running in python ,it prints 12.
> but when running in Ironpython ,it is 14.
> in fact ,i tried it in c like that:
>
>     #include<stdio.h>
>     void main()
>     {
>     #pragma pack(2)
>  struct{
>   unsigned char a;
>   unsigned char b;
>   unsigned char c;
>   unsigned short d;
>   unsigned int e;
>   unsigned char f;
>  }A;
>     #pragma pack()
>  printf("%d\n",sizeof(A));
>     }
> it is 12.
>
> can you tell me why it is and how i can crrect it in Ironpython???

Print the field reprs to see how it's defining the structure in terms
of offsets and sizes. Here's what I get in CPython on Windows:

    from ctypes import *

    class Data(LittleEndianStructure):
        _pack_ = 2
        _fields_ = (('a', c_ubyte),
                    ('b', c_ubyte),
                    ('c', c_ubyte),
                    ('d', c_ushort),
                    ('e', c_uint),
                    ('f', c_ubyte))

    >>> for field, dtype in Data._fields_:
    ...     print field, getattr(Data, field)
    ...
    a <Field type=c_ubyte, ofs=0, size=1>
    b <Field type=c_ubyte, ofs=1, size=1>
    c <Field type=c_ubyte, ofs=2, size=1>
    d <Field type=c_ushort, ofs=4, size=2>
    e <Field type=c_ulong, ofs=6, size=4>
    f <Field type=c_ubyte, ofs=10, size=1>

    >>> alignment(Data)
    2
    >>> sizeof(Data)
    12

The natural alignment is 4 bytes, which requires padding the structure
out to 16 bytes:

    class Data(LittleEndianStructure):
        _fields_ = (('a', c_ubyte),
                    ('b', c_ubyte),
                    ('c', c_ubyte),
                    ('d', c_ushort),
                    ('e', c_uint),
                    ('f', c_ubyte))

    >>> for field, dtype in Data._fields_:
    ...     print field, getattr(Data, field)
    ...
    a <Field type=c_ubyte, ofs=0, size=1>
    b <Field type=c_ubyte, ofs=1, size=1>
    c <Field type=c_ubyte, ofs=2, size=1>
    d <Field type=c_ushort, ofs=4, size=2>
    e <Field type=c_ulong, ofs=8, size=4>
    f <Field type=c_ubyte, ofs=12, size=1>

    >>> alignment(Data)
    4
    >>> sizeof(Data)
    16

HTH

------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
ctypes-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ctypes-users