9

さて、私がやろうとしている基本的な考え方は、バイト配列を short や int などに変換することです。

簡単な例は次のとおりです。

        unsafe
        {
            fixed (byte* byteArray = new byte[5] { 255, 255, 255, 126, 34 })
            {
                short shortSingle = *(short*)byteArray;
                MessageBox.Show((shortSingle).ToString()); // works fine output is -1
            }
        }

さて、私が実際にやろうとしているのは、Stream クラスを拡張することです。拡張された読み取りおよび書き込みメソッド。次のコードで助けが必要です。

unsafe public static T Read<T>(this Stream stream)
        {
            int bytesToRead = sizeof(T); // ERROR: Cannot take the address of, get the size of, or declare a pointer to a managed type ('T')
            byte[] buffer = new byte[bytesToRead];
            if (bytesToRead != stream.Read(buffer, 0, bytesToRead))
            {
                throw new Exception();
            }
            fixed (byte* byteArray = buffer)
            {
                T typeSingle = *(T*)byteArray; // ERROR: Cannot take the address of, get the size of, or declare a pointer to a managed type ('T')
                return typeSingle;
            }
        }

        unsafe public static T[] Read<T>(this Stream stream, int count)
        {
             // haven't figured out it yet. This is where I read and return T arrays
        }

NetworkStream クラスのようなストリームからのデータの書き込みと読み取りに取り組むので、速度のためにポインターを使用する必要があるように感じます。ご協力いただきありがとうございます!

編集:

そして、T配列を返す方法を見つけようとしている間、私はこの問題に直面しました:

unsafe
        {
            fixed (byte* byteArray = new byte[5] { 0, 0, 255, 255, 34 })
            {
                short* shortArray = (short*)byteArray;
                MessageBox.Show((shortArray[0]).ToString()); // works fine output is 0
                MessageBox.Show((shortArray[1]).ToString()); // works fine output is -1

                short[] managedShortArray = new short[2];
                managedShortArray = shortArray; // The problem is, How may I convert pointer to a managed short array? ERROR: Cannot implicitly convert type 'short*' to 'short[]'
            }
        }

概要: バイト配列から指定された型の T または指定された長さの T 配列の指定された型に変換する必要があります。

4

2 に答える 2

5

C# のポインター制限のため、この関数をジェネリックにすることはできません。次の型のいずれかがポインター型である可能性があります。

  • sbyte、byte、short、ushort、int、uint、long、ulong、char、float、double、decimal、または bool。
  • 任意の列挙型。
  • 任意のポインター型。
  • アンマネージ型のみのフィールドを含むユーザー定義の構造体型。

ただし、 T に制限を設定することはできませんwhere T <can be pointer type>where T : structユーザー定義の構造体には参照型のフィールドを含めることができるため、非常に近いですが、十分ではありません。

回避策がありますSystem.Runtime.InteropServices.Marshal.PtrToStructure()(指定されたオブジェクト タイプで動作しない場合は例外をスローするだけです) が、達成されたパフォーマンスの向上も無効になります。

これを行う唯一の方法は、必要なすべての型に対して非ジェネリック関数を作成することだと思います。

于 2012-07-30T18:16:37.547 に答える