[Mono-dev] Marshaling Question

Jonathan Pryor jonpryor at vt.edu
Sat Feb 9 05:12:07 EST 2008


On Sat, 2008-02-09 at 04:06 -0500, Scott Peterson wrote:
> I need to marshal the native cdrom_tocentry struct from linux/cdrom.h
> (http://www.gelato.unsw.edu.au/lxr/source/include/linux/cdrom.h#L218).
> Here's my attempt (which is incorrect). Can someone tell me where I'm
> going wrong?
>
> [StructLayout(LayoutKind.Explicit)]
> struct cdrom_tocentry
> {
>     [FieldOffset(0)]
>     public byte cdte_track;
>     [FieldOffset(1)]
>     public byte cdte_adr;
>     [FieldOffset(5)]
>     public byte cdte_ctrl;
>     [FieldOffset(9)]
>     public byte cdte_format;
>     [FieldOffset(10)]
>     public cdrom_addr cdte_addr;
>     [FieldOffset(14)]
>     public byte cdte_datamode;
> }

The C declaration of cdrom_tocentry doesn't match your C# entry:

        struct cdrom_tocentry
        {
          __u8  cdte_track;
          __u8  cdte_adr  :4;
          __u8  cdte_ctrl :4;
          __u8  cdte_format;
          union cdrom_addr cdte_addr;
          __u8  cdte_datamode;
        };

First of all, there are no packing attributes on this structure, so
using LayoutKind.Explicit is wrong, you want Sequential.

Secondly, cdte_adr and cdte_ctrl are bitfields packed within the same
byte, while you give them separate bytes.  This would be a better
matching C# structure:

        // No [StructLayout] needed, as Sequential is the default.
        struct cdrom_tocentry {
                public byte cdte_track;
                private byte adr_ctrl_info;
                public byte cdte_adr {
                        get {return (adr_ctrl_info & 0xF0) >> 4;}
                        set {adr_ctrl_info = ((adr_ctrl_info & 0x0F) & 
                                ((value & 0xF0) << 4));}
                }
                public byte cdte_ctrl {
                        get {return (adr_ctrl_info & 0x0F);}
                        set {adr_ctrl_info = ((adr_ctrl_info & 0xF0) & 
                                (value & 0x0F));}
                }
                public byte cdte_format
                public cdrom_addr cdte_addr;
                public byte cdte_datamode;
        }

Note that this is untested, but should be a better match (and you should
verify the logic in the cdte_adr and cdte_ctrl properties).

 - Jon




More information about the Mono-devel-list mailing list