简体   繁体   中英

Initialization of a struct in C#?

Some code I'm modifying makes extensive use of structs to communicate with some factory equipment by loading them to or from byte arrays.

Here's a made-up ultra-simplified example of such a struct.

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct K_FOO
{
    public byte a_byte;    // 1 byte
    public BYTE3_TYPE b3;  // 3 bytes
    public int num;        // happens to be 4 bytes
}

BYTE3_TYPE looks like this...

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class BYTE3_TYPE
{
    [System.Runtime.InteropServices.MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
    public byte[] L = new byte[3];
}

If I just do a

    K_FOO origFoo = new K_FOO();

the int and the byte are initialized to 0's, I assume because they are native types, but the byte array b3 is * un *initialized - all nulls. I have to explicitly load it, for example,

    BYTE3_TYPE b3 = new BYTE3_TYPE();
    origFoo.b3 = b3;

... and I couldn't think of any alternative because structs don't take parameterless constructors but the real structs are huge.

But I noticed something interesting. We have routines to copy these structs to and from byte arrays. For example . . .

   public static T ByteArrayToStructure<T>(byte[] buffer) where T : struct
    {
        int length = buffer.Length;
        IntPtr ptr = Marshal.AllocHGlobal(length);   // allocate (length) bytes
        Marshal.Copy(buffer, 0, ptr, length);  // copies into UNmanaged space
        T result = (T)Marshal.PtrToStructure(ptr, typeof(T));
        Marshal.FreeHGlobal(ptr);
        return result;
    }

...and if I call it...

    K_FOO retFoo = ByteArrayToStructure<K_FOO>(buffer.bytes);

... the resulting struct is returned fully initialized, the bytes in the byte array have all had their space allocated so they could be loaded, apparently in the PtrToStructure() call. This implies .Net "knows" how to initialize such a struct. So is there some way to get .Net to do that for me so I can avoid writing hundreds of lines of explicit initialization code? Thanks in advance!

If you make your BYTE3_TYPE a struct instead of a class, the default constructor (calling K_FOO origFoo = new K_FOO(); ) will initialize the entire thing to zero correctly.

This is also likely the correct approach if you're trying to match existing specifications and pass this to custom hardware.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM