2012-02-18 5 views
0

私はバイト配列に別のオブジェクトを変換するためにC++でこのコードの機能を持っている:
C#のような構造組み込み関数で "テンプレートのような型" Tを見ることができるようにするには?

template <typename T> 
static void GetBytesArrayFrom(T value, BYTE *out_array) 
{ 
    union BytesConverter 
    { 
     T value; 
     BYTE bytes_array[sizeof(T)]; 
    }; 

    BytesConverter bc; 
    bc.value = value; 

    memcpy(out_array, bc.bytes_array, sizeof(T)); 
} 

は今、私はC#で同じ機能をしようとしますが、問題を抱えています:

public void GetBytesFrom<T>(T value, byte[] out_array) where T : object 
{ 
    struct BytesConverter 
    { 
     [FieldOffset(0)] 
     T value; //T is unknown here 
     [FieldOffset(0)] 
     byte[] bytes_array = new byte[sizeof(T)]; //and here 
    } 

int test = 0; 
} 

と私は構造体内の関数を全く定義することができないようです。
どのようにC#で同じクールな変換機能を行うことができますか?

+0

オブジェクトをバイト[]変換しようとしていますか?シリアライゼーション? – ken2k

+0

あなたは....それは間違っています。 – Mehrdad

+0

@ ken2k、まあまあですが、私はシリアライゼーションについて知っていますが、私はそれが動作する方法が好きではありません。バイナリデータ、アセンブリ情報などにフィールド名を追加します。私は構造体/クラス/型のデータをC++と同じように表すプレーンバイトを必要とします – Kosmos

答えて

2
static void GetBytes<T>(T obj, byte[] data) 
{ 
    unsafe 
    { 
     fixed (byte* pData = data) 
     { 
      Marshal.StructureToPtr(obj, (IntPtr)pData, false /*careful...*/); 
     } 
    } 
} 
+0

簡単に見えます:Pテストして見てください。ありがとう! – Kosmos

+0

@Kosmos:はい。ただし、**は 'T'に**参照が埋め込まれていないことを** **直接的または間接的に確認してください。そうであれば、配列がメモリ内で移動して無効化されている可能性があるので、ポインタでMarshal.DestroyStructureを使用する必要がありますが、できません。注意してください... – Mehrdad

2

FWIWがstructのメソッドでローカルに明示的に定義されているのは、C#では不可能です(MSILにある可能性があります。他の.NET言語でも、わかりません)。

しかし、Buffer.BlockCopy関数は実質的にmemcpyと同じですが、プリミティブ型(int、double、char、byteなど)でのみ機能します。他のタイプの場合は、Array.Copyを使用する必要があります。

私のC++は少し錆びていますが、私はあなたのC++機能が非プリミティブ型の場合には最高のプラットフォーム/コンパイラ特有だと思います。

関連する問題