0

I am using a TypedReference to set a value in a structure with FieldInfo.SetValueDirect ( Practical uses of TypedReference ).

The overall goal is to have a generic struct-to-buffer and buffer-to-struct function that will read a TCP data stream directly into a c-style structure (Bit fields in C#).

Thanks to some great posts,I have this working for my purposes so far, but I can't find a way to make the TypeReference work.

This code is a stripped version of the project to illustrate the last problem: the structure is being correctly filled from the buffer using FieldInfo.SetValueDirect(), but it loses scope when I leave the routine.

    public class structL4
    {
        public UInt16 Label;
    }

    static class StructConvert
    {
        public static void BufferToStruct<T>(byte[] buffer, int offset, T t) where T : struct
        {
            UInt16 val;
            foreach (System.Reflection.FieldInfo f in t.GetType().GetFields())
            {
                val = BitConverter.ToUint16(buffer,offset);
                TypedReference reference = __makeref(t);
                f.SetValueDirect(reference, val); // t.Label now contains the right value but is lost
            }
        }

        public static void StructToBuffer<T>(T t, byte[] buffer, int offset) where T : struct
        {
            UInt16 val;
            foreach (System.Reflection.FieldInfo f in t.GetType().GetFields())
            {
                val = (UInt16)f.GetValue(t);
                Array.Copy(BitConverter.GetBytes(val), 0, buffer, offset, sizeof(UInt16));
            }
        }
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        structL4 L0 = new structL4();
        structL4 L1 = new structL4();
        byte[] buffer = new byte[4];

        L0.Label = 0x8C54;

        StructConvert.StructToBuffer(L0, buffer, 0);  // works
        StructConvert.BufferToStruct(buffer,0,L1);    // does not work.
    }

I would like BufferToStruct() to act on the passed struct by reference so I don't have to assign it, but I'm having trouble finding a solution the compiler is happy with.

Overall the idea works fine, at least for StructToBuffer(), which I will use with dozens of bitwise C-type structs.

I'm a bit out of my league with TypeReference and FieldInfo methods; have only been using C# for a short time. Any help greatly appreciated!

Community
  • 1
  • 1
buzzard51
  • 1,372
  • 2
  • 23
  • 40

1 Answers1

0

Because "Value Types" are copied and the copy is passed into methods by default, your actual struct isn't modified.

You either return a struct and assign it or pass the struct by ref.

public static void BufferToStruct<T>(byte[] buffer, int offset, ref T t) where T : struct//Note the ref modifier

Then call it as

StructConvert.BufferToStruct(buffer,0,ref L1);
Sriram Sakthivel
  • 72,067
  • 7
  • 111
  • 189