<p>Is there a way of mapping data collected on a stream or array to a data structure or vice-versa?
In C++ this would simply be a matter of casting a pointer to the stream as a data type I want to use (or vice-versa for the reverse)
eg: in C++</p>

<pre><code>Mystruct * pMyStrct = (Mystruct*)&amp;SomeDataStream;
pMyStrct-&gt;Item1 = 25;

int iReadData = pMyStrct-&gt;Item2;
</code></pre>

<p>obviously the C++ way is pretty unsafe unless you are sure of the quality of the stream data when reading incoming data, but for outgoing data is super quick and easy.</p>

[{'answer_id': 2294, 'author': 'gil', 'author_id': 195, 'author_profile': 'https://Stackoverflow.com/users/195', 'pm_score': 2, 'selected': False, 'text': '<p>if its .net on both sides:</p>\n\n<p>think you should use binary serialization and send the byte[] result.</p>\n\n<p>trusting your struct to be fully blittable can be trouble.</p>\n\n<p>you will pay in some overhead (both cpu and network) but will be safe.</p>\n'}, {'answer_id': 2322, 'author': 'Antonio Haley', 'author_id': 390, 'author_profile': 'https://Stackoverflow.com/users/390', 'pm_score': 2, 'selected': False, 'text': '<p>If you need to populate each member variable by hand you can generalize it a bit as far as the primitives are concerned by using FormatterServices to retrieve in order the list of variable types associated with an object. I\'ve had to do this in a project where I had a lot of different message types coming off the stream and I definitely didn\'t want to write the serializer/deserializer for each message. </p>\n\n<p>Here\'s the code I used to generalize the deserialization from a byte[].</p>\n\n<pre><code>public virtual bool SetMessageBytes(byte[] message)\n    {\n        MemberInfo[] members = FormatterServices.GetSerializableMembers(this.GetType());\n        object[] values = FormatterServices.GetObjectData(this, members);\n        int j = 0;\n\n        for (int i = 0; i &lt; members.Length; i++)\n        {\n            string[] var = members[i].ToString().Split(new char[] { \' \' });\n            switch (var[0])\n            {\n                case "UInt32":\n                    values[i] = (UInt32)((message[j] &lt;&lt; 24) + (message[j + 1] &lt;&lt; 16) + (message[j + 2] &lt;&lt; 8) + message[j + 3]);\n                    j += 4;\n                    break;\n                case "UInt16":\n                    values[i] = (UInt16)((message[j] &lt;&lt; 8) + message[j + 1]);\n                    j += 2;\n                    break;\n                case "Byte":\n                    values[i] = (byte)message[j++];\n                    break;\n                case "UInt32[]":\n                    if (values[i] != null)\n                    {\n                        int len = ((UInt32[])values[i]).Length;\n                        byte[] b = new byte[len * 4];\n                        Array.Copy(message, j, b, 0, len * 4);\n                        Array.Copy(Utilities.ByteArrayToUInt32Array(b), (UInt32[])values[i], len);\n                        j += len * 4;\n                    }\n                    break;\n                case "Byte[]":\n                    if (values[i] != null)\n                    {\n                        int len = ((byte[])values[i]).Length;\n                        Array.Copy(message, j, (byte[])(values[i]), 0, len);\n                        j += len;\n                    }\n                    break;\n                default:\n                    throw new Exception("ByteExtractable::SetMessageBytes Unsupported Type: " + var[1] + " is of type " +  var[0]);\n            }\n        }\n        FormatterServices.PopulateObjectMembers(this, members, values);\n        return true;\n    }\n</code></pre>\n'}, {'answer_id': 2490, 'author': 'lubos hasko', 'author_id': 275, 'author_profile': 'https://Stackoverflow.com/users/275', 'pm_score': 5, 'selected': True, 'text': '<p>Most people use .NET serialization (there is faster binary and slower XML formatter, they both depend on reflection and are version tolerant to certain degree)</p>\n\n<p>However, if you want the fastest (unsafe) way - why not:</p>\n\n<p>Writing:</p>\n\n<pre><code>YourStruct o = new YourStruct();\nbyte[] buffer = new byte[Marshal.SizeOf(typeof(YourStruct))];\nGCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);\nMarshal.StructureToPtr(o, handle.AddrOfPinnedObject(), false);\nhandle.Free();\n</code></pre>\n\n<p>Reading:</p>\n\n<pre><code>handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);\no = (YourStruct)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(YourStruct));\nhandle.Free();\n</code></pre>\n'}, {'answer_id': 1617761, 'author': 'Simon Buchan', 'author_id': 20135, 'author_profile': 'https://Stackoverflow.com/users/20135', 'pm_score': 3, 'selected': False, 'text': '<p>In case lubos hasko\'s answer was not unsafe enough, there is also the <strong>really</strong> unsafe way, using\npointers in C#. Here\'s some tips and pitfalls I\'ve run into:</p>\n\n<pre><code>using System;\nusing System.Runtime.InteropServices;\nusing System.IO;\nusing System.Diagnostics;\n\n// Use LayoutKind.Sequential to prevent the CLR from reordering your fields.\n[StructLayout(LayoutKind.Sequential)]\nunsafe struct MeshDesc\n{\n    public byte NameLen;\n    // Here fixed means store the array by value, like in C,\n    // though C# exposes access to Name as a char*.\n    // fixed also requires \'unsafe\' on the struct definition.\n    public fixed char Name[16];\n    // You can include other structs like in C as well.\n    public Matrix Transform;\n    public uint VertexCount;\n    // But not both, you can\'t store an array of structs.\n    //public fixed Vector Vertices[512];\n}\n\n[StructLayout(LayoutKind.Sequential)]\nunsafe struct Matrix\n{\n    public fixed float M[16];\n}\n\n// This is how you do unions\n[StructLayout(LayoutKind.Explicit)]\nunsafe struct Vector\n{\n    [FieldOffset(0)]\n    public fixed float Items[16];\n    [FieldOffset(0)]\n    public float X;\n    [FieldOffset(4)]\n    public float Y;\n    [FieldOffset(8)]\n    public float Z;\n}\n\nclass Program\n{\n    unsafe static void Main(string[] args)\n    {\n        var mesh = new MeshDesc();\n        var buffer = new byte[Marshal.SizeOf(mesh)];\n\n        // Set where NameLen will be read from.\n        buffer[0] = 12;\n        // Use Buffer.BlockCopy to raw copy data across arrays of primitives.\n        // Note we copy to offset 2 here: char\'s have alignment of 2, so there is\n        // a padding byte after NameLen: just like in C.\n        Buffer.BlockCopy("Hello!".ToCharArray(), 0, buffer, 2, 12);\n\n        // Copy data to struct\n        Read(buffer, out mesh);\n\n        // Print the Name we wrote above:\n        var name = new char[mesh.NameLen];\n        // Use Marsal.Copy to copy between arrays and pointers to arrays.\n        unsafe { Marshal.Copy((IntPtr)mesh.Name, name, 0, mesh.NameLen); }\n        // Note you can also use the String.String(char*) overloads\n        Console.WriteLine("Name: " + new string(name));\n\n        // If Erik Myers likes it...\n        mesh.VertexCount = 4711;\n\n        // Copy data from struct:\n        // MeshDesc is a struct, and is on the stack, so it\'s\n        // memory is effectively pinned by the stack pointer.\n        // This means \'&amp;\' is sufficient to get a pointer.\n        Write(&amp;mesh, buffer);\n\n        // Watch for alignment again, and note you have endianess to worry about...\n        int vc = buffer[100] | (buffer[101] &lt;&lt; 8) | (buffer[102] &lt;&lt; 16) | (buffer[103] &lt;&lt; 24);\n        Console.WriteLine("VertexCount = " + vc);\n    }\n\n    unsafe static void Write(MeshDesc* pMesh, byte[] buffer)\n    {\n        // But byte[] is on the heap, and therefore needs\n        // to be flagged as pinned so the GC won\'t try to move it\n        // from under you - this can be done most efficiently with\n        // \'fixed\', but can also be done with GCHandleType.Pinned.\n        fixed (byte* pBuffer = buffer)\n            *(MeshDesc*)pBuffer = *pMesh;\n    }\n\n    unsafe static void Read(byte[] buffer, out MeshDesc mesh)\n    {\n        fixed (byte* pBuffer = buffer)\n            mesh = *(MeshDesc*)pBuffer;\n    }\n}\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/2256', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/379/']