I have the following unmanaged code in 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;
Here's my managed conversion, I'm able to deduce sizes and layout the unions properly, but I don't know how to handle the ifdef condition from c code to c#
[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;
}
Can anyone tell me how to handle the if conditions and unions ?
Once compiled, structs in C and C# are static, there is no difference im this respect. #ifdef's also work pretty much the same way, no difference here either.
The only thing to realize here is that, based on the value of PNIO_ALARM_OLD_STRUC, the compilation can yield two different structs. You need to compile your C and C# code the same way, so that they yield the same struct definitions.
If you want to handle both C versions with one C# version, you need to define two different C# structs so that they both appear in one compilation unit. Then you need to figure out which struct to use when.