2

メモリ内にバイナリ シリアル化されたオブジェクトがあり、C# でポインター (unsafae コード) を使用してメモリから読み取りたいと考えています。メモリストリームから読み込んでいる次の関数を見てください。

static Results ReadUsingPointers(byte[] data)
{
    unsafe
    {
        fixed (byte* packet = &data[0])
        {
            return *(Results*)packet;
        }
    }
}

このreturn *(Results*)packet;ステートメントで、コンパイル時の例外「マネージド型の結果のアドレスを取得したり、サイズを取得したり、ポインターを宣言したりできません」

これが私の構造です

public struct Results
{
    public int Id;
    public int Score;
    public char[] Product;
}

私の理解によると、構造体のすべてのプロパティは blittable プロパティです。なぜこのエラーが発生するのですか?また、構造体で char[] を使用する必要がある場合はどうすればよいですか?

EDIT-1 さらに説明させてください(オブジェクトが嘲笑されていることに注意してください)...

背景:Resultsオブジェクトの配列があり、バイナリ シリアル化を使用してそれらをシリアル化しました。ここで、プログラムの後の段階で、データ ボリュームが非常に大きいため、メモリ内のデータをできるだけ早く逆シリアル化する必要があります。そこで、安全でないコードがどのように役立つかを試していました。

構造に が含まれていない場合、public char[] Product;かなりの速度でデータが返されます。しかし、char[] を使用すると、エラーが発生します (コンパイラがそうする必要があります)。このコンテキストで char[] で機能するソリューションを探していました。

4

2 に答える 2

2

MSDN は次のように述べています

次の型のいずれかがポインター型である可能性があります。

  • sbyte、byte、short、ushort、int、uint、long、ulong、char、float、double、decimal、または bool。

  • 任意の列挙型。

  • 任意のポインター型。

  • アンマネージ型のみのフィールドを含むユーザー定義の構造体型。

したがって、構造体を次のように定義して、コンパイラ エラーを修正できます。

public struct Results
{
    public int Id;
    public int Score;
    // Don't actually do this though.
    public unsafe char* Product;
}

このようにして、配列の最初の要素を指すことができます。

ただし、編集した質問に基づいて、ここでは別のアプローチが必要です。

結果オブジェクトの配列があり、バイナリ シリアル化を使用してそれらをシリアル化しました。さて、プログラムの後の段階で、メモリ内のデータをできるだけ早く逆シリアル化する必要があります

通常はBinaryFormatterその目的で使用します。それが遅すぎる場合、問題はそもそもシリアル化を回避できるかどうかです。

于 2014-04-21T08:04:35.243 に答える