2016-09-29 16 views
1

私はIntPtrから、周期的なパケットを送信するハードウェアソースからの構造化データに着手しています。スレッドはIntptrバッファからパケットをコピーし、byte []をキューに入れます。その後、キューが読み取られ、byte []はthis answerを使用して構造体に変換され、Packet型のコレクション(配列)になります。構造体の定義を複製せずにc#構造体の配列を配列の構造体に変換する方法

struct Packet { 
    long time; 
    int field1; 
    short field2; 
} 

Packet[] array_of_packet; 

私はそれが配列の構造であるかのようにデータを使用ししたいと思います。

このフォーマットは、他の機能はベクトルとしてそれらを使用することができます:

Plot(data.time, data.field1); 
+0

私は迷った!とにかく、それは長い[]時間でなくてはならない[0] – Nair

+0

まったく違ったレイアウトです。手動ですべてをアイテムごとにコピーする必要があります。 – Luaan

+0

あなたは本当に[不変の構造体](http://stackoverflow.com/questions/3751911/why-are-c-sharp-structs-immutable)の作成に目を通すべきです。 – juharr

答えて

3

あなたが望むすべてが配列に変換する簡単な方法であれば、単にLINQを使用します。

Plot (array_of_packet.Select(p => p.time).ToArray(), 
     array_of_packet.Select(p => p.field1).ToArray()); 

の場合コピーのコストをかけずにメモリ内のデータを並べ替える魔法の方法を探しているなら、あなたは不運です。 ;-)

0

LINQの

data.time = array_of_packet.Select(p => p.time).ToArray(); 
data.field1 = array_of_packet.Select(p => p.field1).ToArray(); 
data.field2 = array_of_packet.Select(p => p.field2).ToArray(); 

とかなり簡単にあなたはプロパティpublic

がよりeffecientソリューションは、あなたがラッパーを作成することができ

var time = new long[array_of_packet.Length]; 
var field1 = new int[array_of_packet.Length]; 
var field2 = new short[array_of_packet.Length]; 
for(int i = 0; i < array_of_packet.Length; i++) 
{ 
    time[i] = array_of_paket[i].time; 
    field1[i] = array_of_paket[i].field1; 
    field2[i] = array_of_paket[i].field2; 
} 

data.time = time; 
data.field1 = field1; 
data.field2 = field2; 
0

かもしれないようにする必要がありますけど配列のようなアクセサ構文を公開するクラス:

class ArrayWrapper<T, TField> 
{ 
    Func<T, TField> getField; 
    T[] array; 

    public ArrayWrapper(T[] array, Func<T, TField> getField) 
    { 
     this.array = array; 
     this.getField = getField; 
    } 

    public TField this[int index] 
    { 
     get { return this.getField(this.array[index]);} 
    } 

} 

そこで、このような単純なヘルパーメソッドで:

:あなたが望むように使用することができた...

var data = new 
{ 
    time = Wrap(array_of_packet, p => p.time), 
    field1 = Wrap(array_of_packet, p => p.field1), 
    field2 = Wrap(array_of_packet, p => p.field2) 
}; 

ArrayWrapper<T, TField> Wrap<T, TField>(T[] array, Func<T, TField> getField) 
{ 
    return new ArrayWrapper<T, TField>(array, getField); 
} 

あなたはこのようなオブジェクトを作成することができます

Plot(data.time, data.field1); 

具体的なニーズに応じて、さまざまな方法でこれを詳しく説明できます。

  • IList<TField>のようなインターフェイスを実装するようにして、Plot()を基になる型には無関係に書くことができます。パフォーマンスではなく、デリゲート(Func<,>)を使用するよりも、高い優先度である場合、あなたはArrayWrapper定義にwhere T is structを追加し、ArrayWrapperはそのコンストラクタのパラメータとしてバイトオフセットを取るかもしれない
  • (配列はすでに。IList<TField>を実装)、および行いますいくつかのunsafeマジックフィールドのデータに迅速にアクセスする。
+1

私が質問したとき - これは私が探していたものです - – pathfinder

+0

@brainfog:私はそれがあると思いました。私はLINQが大好きですが、データを複数の配列にコピーしないようにしていたようです。 – StriplingWarrior

+0

最初は私は段階的な方法で考えていました:1)データを収集する2)構造体とその配列に変換する3)元の構造体を再入力せずに配列の構造に変換する彼らは後で変更することができます) – pathfinder

関連する問題