Pemetaan Aliran data struktur data di C#

Apakah ada cara pemetaan data yang dikumpulkan pada suatu aliran atau array struktur data atau sebaliknya? Dalam C++ ini hanya akan menjadi masalah casting pointer ke sungai sebagai tipe data yang ingin saya gunakan (atau sebaliknya untuk reverse) misalnya: dalam C++

Mystruct * pMyStrct = (Mystruct*)&SomeDataStream;
pMyStrct->Item1 = 25;

int iReadData = pMyStrct->Item2;

jelas C++ cara ini cukup aman kecuali anda yakin kualitas aliran data ketika membaca data yang masuk, tapi untuk keluar data super cepat dan mudah.

Larutan

Kebanyakan orang menggunakan .NET serialisasi (ada yang lebih cepat biner dan lebih lambat XML formatter, mereka berdua tergantung pada refleksi dan versi toleran terhadap tingkat tertentu)

Namun, jika anda ingin tercepat (aman) cara - mengapa tidak:

Menulis:

YourStruct o = new YourStruct();
byte[] buffer = new byte[Marshal.SizeOf(typeof(YourStruct))];
GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
Marshal.StructureToPtr(o, handle.AddrOfPinnedObject(), false);
handle.Free();

Membaca:

handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
o = (YourStruct)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(YourStruct));
handle.Free();
Komentar (0)

Dalam kasus lubos hasko's jawaban yang tidak aman yang cukup, ada juga yang *benar-benar *** cara yang tidak aman, menggunakan pointer dalam C#. Berikut ini's beberapa tips dan perangkap saya've berjalan ke:


using System;
using System.Runtime.InteropServices;
using System.IO;
using System.Diagnostics;

// Use LayoutKind.Sequential to prevent the CLR from reordering your fields.
[StructLayout(LayoutKind.Sequential)]
unsafe struct MeshDesc
{
    public byte NameLen;
    // Here fixed means store the array by value, like in C,
    // though C# exposes access to Name as a char*.
    // fixed also requires 'unsafe' on the struct definition.
    public fixed char Name[16];
    // You can include other structs like in C as well.
    public Matrix Transform;
    public uint VertexCount;
    // But not both, you can't store an array of structs.
    //public fixed Vector Vertices[512];
}

[StructLayout(LayoutKind.Sequential)]
unsafe struct Matrix
{
    public fixed float M[16];
}

// This is how you do unions
[StructLayout(LayoutKind.Explicit)]
unsafe struct Vector
{
    [FieldOffset(0)]
    public fixed float Items[16];
    [FieldOffset(0)]
    public float X;
    [FieldOffset(4)]
    public float Y;
    [FieldOffset(8)]
    public float Z;
}

class Program
{
    unsafe static void Main(string[] args)
    {
        var mesh = new MeshDesc();
        var buffer = new byte[Marshal.SizeOf(mesh)];

        // Set where NameLen will be read from.
        buffer[0] = 12;
        // Use Buffer.BlockCopy to raw copy data across arrays of primitives.
        // Note we copy to offset 2 here: char's have alignment of 2, so there is
        // a padding byte after NameLen: just like in C.
        Buffer.BlockCopy("Hello!".ToCharArray(), 0, buffer, 2, 12);

        // Copy data to struct
        Read(buffer, out mesh);

        // Print the Name we wrote above:
        var name = new char[mesh.NameLen];
        // Use Marsal.Copy to copy between arrays and pointers to arrays.
        unsafe { Marshal.Copy((IntPtr)mesh.Name, name, 0, mesh.NameLen); }
        // Note you can also use the String.String(char*) overloads
        Console.WriteLine("Name: " + new string(name));

        // If Erik Myers likes it...
        mesh.VertexCount = 4711;

        // Copy data from struct:
        // MeshDesc is a struct, and is on the stack, so it's
        // memory is effectively pinned by the stack pointer.
        // This means '&' is sufficient to get a pointer.
        Write(&mesh, buffer);

        // Watch for alignment again, and note you have endianess to worry about...
        int vc = buffer[100] | (buffer[101] 
Komentar (0)

jika .net pada kedua sisi:

berpikir anda harus menggunakan biner serialisasi dan mengirim byte[] hasilnya.

percaya struct anda untuk sepenuhnya blittable dapat menjadi masalah.

anda akan membayar dalam beberapa overhead (baik cpu dan jaringan) tetapi akan aman.

Komentar (0)

Jika anda perlu untuk mengisi masing-masing variabel anggota dengan tangan anda dapat menggeneralisasi sedikit sejauh primitif yang bersangkutan dengan menggunakan FormatterServices untuk mengambil dalam rangka daftar jenis variabel yang berhubungan dengan suatu objek. I've harus melakukan ini dalam sebuah proyek di mana saya punya banyak berbagai jenis pesan yang datang dari sungai dan aku pasti tidak't ingin menulis serializer/deserializer untuk setiap pesan.

Berikut ini's kode yang saya digunakan untuk menggeneralisasi deserialization dari byte[].


public virtual bool SetMessageBytes(byte[] message)
    {
        MemberInfo[] members = FormatterServices.GetSerializableMembers(this.GetType());
        object[] values = FormatterServices.GetObjectData(this, members);
        int j = 0;

        for (int i = 0; i < members.Length; i++)
        {
            string[] var = members[i].ToString().Split(new char[] { ' ' });
            switch (var[0])
            {
                case "UInt32":
                    values[i] = (UInt32)((message[j] 
Komentar (0)