Frage

ein Objekt und Fieldinfo ein Objekt gegeben, ich brauche die tatsächliche Bytes Darstellung des Feldes zu erhalten. Ich weiß, dass das Feld entweder int,Int32,uint,short etc.

Wie kann ich die aktuelle Byte-Darstellung? BinaryFormatter.Serialize wird nicht helfen, da es mir mehr Informationen geben werde, als ich brauche (es zeichnet auch Namen usw. eingeben). Die Marshal Klasse scheint nicht Einrichtungen zu haben Bytes Array zu verwenden (aber vielleicht bin ich etwas fehlt).

Danke

War es hilfreich?

Lösung

Sie können auch Code versuchen, wie die folgenden, wenn, was Sie eigentlich wollen, ist es, Strukturen als Byte-Array übertragen:

int rawsize = Marshal.SizeOf(value);
byte[] rawdata = new byte[rawsize];
GCHandle handle = GCHandle.Alloc(rawdata, GCHandleType.Pinned);
Marshal.StructureToPtr(value, handle.AddrOfPinnedObject(), false);
handle.Free();

Dieses wandelt das gegebene Objekt Wert in den Byte-Array rawdata. Ich habe dies aus Code genommen, die ich zuvor schrieb, und Sie können es an Ihre Bedürfnisse anpassen müssen, um es tatsächlich funktioniert. Ich benutzen es für die Kommunikation mit einiger Hardware mit benutzerdefinierten Strukturen, aber es sollte auch für integrierte Typen arbeitet (nach allem, sie sind Strukturen, nicht wahr?)

Um Strukturelemente richtig ausgerichtet sind, verwenden Sie das Attribut StructLayout zu machen Ein-Byte-Ausrichtung angeben:

[StructLayout(LayoutKind.Sequential, Pack = 1)]

Und dann verwenden die MarshalAs nach Bedarf Attribut für Felder, z.B. für die Inline-Arrays:

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
byte[] _state;

Der Code die Struktur wieder aus dem Byte-Array zu erhalten, ist so etwas wie folgt aus:

public T GetValue<T>()
{
    GCHandle handle = GCHandle.Alloc(RawValue, GCHandleType.Pinned);
    T structure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), 
                      typeof(T));
    handle.Free();
    return structure;
}

Natürlich werden Sie den Typ wissen müssen Sie dafür arbeiten wollen.

Beachten Sie, dass diese endianness nicht für sich behandelt. In meinem Projekt waren die meisten Felder ein Byte nur, damit es nicht egal war, aber für die wenigen Bereiche, in denen es tat, ich habe gerade die Felder privaten und hinzugefügt öffentlichen Eigenschaften, die Pflege der endianness nehmen würde ( Jon Skeet Link von einem Kommentar zu seiner Antwort kann Ihnen helfen, ich einige Hilfsfunktionen für diese geschrieben, da ich nur benötigt wenige).

Als ich dies erforderlich ist, habe ich eine Message-Klasse, die den Rohwert speichern würde (daher die GetValue-Methode, wird der Code an der Spitze ist eigentlich der Körper einer SetValue-Methode) und hatte einige schöne bequeme Methode, den Wert zu erhalten, formatierte etc.

Andere Tipps

Mit BitConverter.GetBytes ()

Sie werden zuerst den Wert zu konvertieren, um es nativen Typ ist, als BitConverter verwenden, um das Bytes zu bekommen:

byte[] Bytes;

if (valType == typeof(int))
{
    int intVal = (int) GetFieldValue(....);
    Bytes = BitConverter.GetBytes(intVval);
} 
else if (valType == typeof(long))
{
    int lngVal = (long) GetFieldValue(....);
    Bytes = BitConverter.GetBytes(lngVal);
} else ....

Wollen Sie die endgültige In-Memory-Darstellung? BitConverter.GetBytes (mit einer Überlast in geeigneter Weise durch Reflexion gewählt) kehren Sie a Byte-Darstellung, aber nicht unbedingt das, was es ist zur Zeit im Speicher.

Vielleicht, wenn Sie weitere Informationen geben, warum Sie dies wünschen, werden wir besser in der Lage sein, Ihnen zu helfen.

EDIT: Ich möchte, dass in jedem vernünftigen Fall füge ich von, BitConverter denken kann, wird Sie die gleiche Darstellung wie im Speicher geben - aber es kann ungerade Situationen sein endianness beteiligt und möglicherweise seltsame Architekturen mit unterschiedlichen Punktdarstellungen schwimmend, die zu seltsamen Ergebnissen führen könnten.

EDIT: Hier ist ein komplettes Beispielprogramm zeigt, wie Sie darüber gehen könnten:

using System;
using System.Reflection;

public class Test
{
    public int x = 300;

    static void Main()
    {
        Test instance = new Test();
        FieldInfo field = typeof(Test).GetField("x");

        MethodInfo converter = typeof(BitConverter).GetMethod("GetBytes", 
            new Type[] {field.FieldType});

        if (converter == null)
        {
            Console.WriteLine("No BitConverter.GetBytes method found for type "
                + field.FieldType);            
        }
        else
        {
            byte[] bytes = (byte[]) converter.Invoke(null,
                new object[] {field.GetValue(instance) });
            Console.WriteLine("Byte array: {0}", BitConverter.ToString(bytes));
        }        
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top