2011-08-12 9 views
0

このアプリケーションは、組み込み制御および監視システム用のWindowsベースのC#ユーザーインターフェイスです。列挙型を使用してビット配列をインデックス化する

組み込みシステム(C言語で記述)は、c#アプリケーションに送信するフォールトのテーブルを保持します。障害テーブルは、各障害ごとに1ビットを含み、構造内に格納されます。私は、今

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のどのバージョンあなたはameworkを使用しますか? –

答えて

0

enumにFlags属性を追加します。あなたがあなたの構造体はあなたが(が、レイアウトを指定することを確認する必要がありますが、ほとんど同じ方法で作成することができますMarshal.OffsetOf

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

と構造体の要素のオフセットを取得することができhttp://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=EN-US&k=k(SYSTEM.FLAGSATTRIBUTE);k(TargetFrameworkMoniker-%22.NETFRAMEWORK%2cVERSION%3dV4.0%22);k(DevLang-CSHARP)&rd=true

0

を参照してください。これはstructがどのようにインスタンス化されるかに依存していると思います)。

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

しかし...問題は、列挙型が付属しています。 Enum値は時定数をコンパイルする必要があり、Marshal.OffsetOfはそうではありません。したがって、代わりにクラスの静的メンバーとしてオフセットを格納する必要があります。

私はまた、あなたがそれらを持っていれば、これらのオフセットを実際に使用するためにおそらく安全でないコードに迷い込む必要があると思います。そして、あなたがマネージコードでやりたいことにアプローチする方が良いでしょう。

+0

ありがとうJames - 私は別の方法を探す必要があると思います –

+0

ここの目的は何ですか?あなたは非管理コードから構造体を受け取っています(p/invoke?を介して) - 構造体に適切なレイアウト属性があれば、適切に整列したメンバーを介して構造体にアクセスできます。動的に(ある意味で)アクセスしたい場合は、例えばメモリオフセットを使いこなす代わりに、リフレクションを使うことができます。まだそれをクラスにして、必要なプロパティにアクセスするためのメンバーを追加する方がいいです。データの内部表現を無関係にする。 –

+0

目的は簡単です。 (早い時期に返されたおっとなしの返品) –

0

ビット/フラグをマッピングする列挙型を作成できますが、32ビットを超えるマップはできません。

あなたの例では、私はいくつかの長い(64ビット)のconstを作成します。配列が非常に長い場合(例えば、最初の配列)、ビットの制限は解決されません。

別のトリックは、配列のビット位置にビットの値(ブール値)を与える静的関数を作成しています。この場合、位置(定数)は確実にintの範囲内にあります。

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

希望します。

0

ビットオフセットバイトの各セット内に指定する列挙型の作成:

enum PowerSupplyFaults 
{ 
    PowerSupplyFault1, PowerSupplyFault2, PowerSupplyFault3 
} 

PowerSupplyFault1等、1として自動割り当て0、FAULT2なり

あなたがCのバージョンを反映する構造体を受け取ると仮定:

struct FaultTable 
{ 
    // ... 

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

    // ... 
} 

あなたがBitArrayとインデックスでテストにバイトを供給することによって、障害のためにテストすることができます。また

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); 
    } 
}