2011-08-12 73 views
0

该应用程序是嵌入式控制和监视系统的基于Windows的C#用户界面。使用枚举来索引位数组

嵌入式系统(用C语言编写)维护一个发送给c#应用程序的故障表。故障表包含每个故障一位,存储在结构中。现在从用户的角度来看接口表的点是有点稀疏的 - 只有一些故障位,我们感兴趣的是,这样的结构可以表示如下:现在

typedef struct 
{ 
    BYTE FaultsIAmNotInterestedIn0[14]; 
    BYTE PowerSupplyFaults[4]; 
    BYTE FaultsIAmNotInterestedIn1[5]; 
    BYTE MachineryFaults[2]; 
    BYTE FaultsIAmNotInterestedIn2[5]; 
    BYTE CommunicationFaults[4]; 
}FAULT_TABLE; 

,我希望能够给指数的每个故障位,我很感兴趣,在CI会使用一个枚举来做到这一点。

typedef enum 
{ 
    FF_PSU1 = offsetof(FAULT_TABLE,PowerSupplyFaults)*8, 
    FF_PSU2, 
    FF_PSU3, 
    FF_PSU4, 
    FF_PSU5, 
    FF_PSU6, 
    FF_PSU7, 
    FF_PSU8, 
    FF_PSU9, 
    FF_PSU10, 
    FF_PSU11, 
    FF_PSU12, 
    FF_PSU13, 

    FF_MACHINERY1 = offsetof(FAULT_TABLE,MachineryFaults)*8, 
    FF_MACHINERY2, 
    FF_MACHINERY3, 
    FF_MACHINERY4, 
    FF_MACHINERY5, 
    FF_MACHINERY6, 
    FF_MACHINERY7, 
    FF_MACHINERY8, 
    FF_MACHINERY9, 
    FF_MACHINERY10, 

    FF_COMMS1 = offsetof(FAULT_TABLE,CommunicationFaults)*8, 
    FF_COMMS2, 
    FF_COMMS3, 
    FF_COMMS4, 
    FF_COMMS5, 
    FF_COMMS6, 
    FF_COMMS7, 
    FF_COMMS8, 
    FF_COMMS9, 
    FF_COMMS10, 
    FF_COMMS11, 
    FF_COMMS12, 
    FF_COMMS13 
}FAULT_FLAGS; 

有没有办法,我可以创造一个类似枚举的方式,基于数据结构C#?

+0

哪个版本的.net fr你会用什么样的工作? –

回答

0

与你可以得到抵消结构的元素Marshal.OffsetOf

http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.offsetof.aspx

你的结构可以在几乎相同的方式来创建,虽然你需要确保你指定布局(虽然我想这取决于结构是如何实例化的)。

http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.structlayoutattribute(v=vs.71).aspx

但是......问题将带着枚举。枚举值需要是编译时间常量,Marshal.OffsetOf不是。因此,您可能必须将偏移量存储为类的静态成员。

我也认为你可能不得不偏离到不安全的代码中,以便在你拥有这些偏移量时真正使用这些偏移量 - 并且可能有更好的方法来处理任何你想在托管代码中执行的操作。

+0

谢谢詹姆斯 - 我想我将不得不寻找另一种方法 –

+0

这里的目标是什么?您是从非托管代码接收结构(通过p/invoke?) - 只要结构具有适当的布局属性,其中的所有内容都可以通过适当对齐的成员进行访问。如果你想动态访问它(从某种意义上说),你可以使用反射而不是搞乱内存偏移。最好还是让它成为一个班级并添加成员以访问所需的属性。使数据的内部表示无关紧要。 –

+0

目标是简单。 (哎呀 - 过早按回复 - 更多来) –

0

您可以创建一个枚举来映射位/标志,但映射不能超过32位。

在你的例子中,我会创建几个常量(64位)。当数组很长时(例如第一个),这不会解决位限制问题。

另一个技巧是创建一个静态函数,该函数根据数组中的位位置给出该位(作为布尔值)的值。在这种情况下,位置(是一个常量)肯定在int范围内。

public static bool GetBit(byte[] buffer, int pos) 
{ 
    return (buffer[pos >> 3] & (1 << (pos & 7)) != 0); 
} 

希望它有帮助。

0

创建指定枚举比特偏移每一组的字节内:

enum PowerSupplyFaults 
{ 
    PowerSupplyFault1, PowerSupplyFault2, PowerSupplyFault3 
} 

PowerSupplyFault1将自动分配的0,如FAULT2 1等

假设你收到镜像C版本一个结构:通过由索引字节馈送到BitArray和测试

struct FaultTable 
{ 
    // ... 

    public byte[] PowerSupplyFaults; 
    public byte[] MachineFaults; 

    // ... 
} 

可以测试故障:

FaultTable faults = GetFaultTable(); 
BitArray psu_faults = new BitArray(fault_table.PowerSupplyFaults); 

if (psu_faults[ (int)PowerSupplyFaults.PowerSupplyFault3 ]) 
{ 
    // ... 
} 

或者,也可以遍历所有位并查看哪些设置:

for (int i = 0; i < psu_faults.Length; i++) 
{ 
    if (psu_faults[ i ]) 
    { 
     Console.WriteLine("PSU fault: {0}", (PowerSupplyFaults)i); 
    } 
}