马歇尔与c#中的ifdef和联盟结合

时间:2013-12-06 13:03:53

标签: c# struct marshalling union conditional-compilation

我在C

中有以下非托管代码
typedef struct {         
PNIO_UINT16    AlarmSpecifier;
PNIO_UINT32    ModIdent;              
PNIO_UINT16    UserAlarmDataLen;    

#ifdef PNIO_ALARM_OLD_STRUC
    PNIO_UINT8     UserAlarmData[PNIO_MAX_ALARM_DATA_LEN]; 
#else
    union {
            PNIO_ALARM_DATA_MAINTENANCE_DIAGNOSIS m_diag; /* Another struct of size 20bytes */
            PNIO_UINT8     UserAlarmData[PNIO_MAX_ALARM_DATA_LEN]; /* Byte array, PNIO_MAX_ALARM_DATA_LEN=1472 */
          } UAData;
#endif

} ATTR_PACKED PNIO_ALARM_INFO;

这是我的托管转换,我能够正确推断出大小和布局工会,但我不知道如何处理从c代码到c#的ifdef条件

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct PNIO_ALARM_INFO
{
    [FieldOffset(0)]
    public ushort AlarmSpecifier;

    [FieldOffset(2)]
    public uint ModIdent;

    [FieldOffset(6)]
    public ushort UserAlarmDataLen;

    // ifdef condition is true use this field
    //[FieldOffset(8)]
    //[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1472)]
    //public byte[] UserAlarmData;

    // ifdef condition false use following fields
    [FieldOffset(8)]
    public PNIO_ALARM_DATA_MAINTENANCE_DIAGNOSIS m_diag;

    [FieldOffset(28)]
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1472)]
    public byte[] UserAlarmData;
}

有谁能告诉我如何处理if条件和工会?

1 个答案:

答案 0 :(得分:0)

编译完成后,C和C#中的结构是静态的,这方面没有区别。 #ifdef的工作方式也大致相同,这里也没有区别。

这里唯一要认识到的是,根据PNIO_ALARM_OLD_STRUC的值,编译可以产生两个不同的结构。您需要以相同的方式编译C和C#代码,以便它们产生相同的结构定义。

如果要同时处理具有一个C#版本的两个C版本,则需要定义两个不同的C#结构,以便它们都出现在一个编译单元中。然后你需要确定在什么时候使用哪个结构。