[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