在 c# 中使用 ifdef 和联合的 Marshall 结构
Posted
技术标签:
【中文标题】在 c# 中使用 ifdef 和联合的 Marshall 结构【英文标题】:Marshall Structs with ifdef's and unions in c# 【发布时间】:2013-12-06 13:03:53 【问题描述】:我在 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 条件和联合?
【问题讨论】:
#ifdef in C#的可能重复 @BlackBear 我的要求是不要定义“条件编译符号”。另一方面,“条件属性”听起来很有希望。你能告诉我如何在条件属性中使用“静态只读布尔”字段吗?因为我试过了,而且只有在结构内定义一个 bool 字段时才有可能。而且我不想在我的结构中定义一个 bool 字段。 【参考方案1】:编译后,C 和 C# 中的结构是静态的,在这方面没有区别。 #ifdef 的工作方式也几乎相同,这里也没有区别。
这里唯一要意识到的是,根据 PNIO_ALARM_OLD_STRUC 的值,编译可以产生两个不同的结构。您需要以相同的方式编译您的 C 和 C# 代码,以便它们产生相同的结构定义。
如果您想用一个 C# 版本处理两个 C 版本,您需要定义两个不同的 C# 结构,以便它们都出现在一个编译单元中。然后你需要弄清楚什么时候使用哪个结构。
【讨论】:
以上是关于在 c# 中使用 ifdef 和联合的 Marshall 结构的主要内容,如果未能解决你的问题,请参考以下文章
在 C# 中使用非原始类型重新创建 C++ 联合类型时出现对齐错误