Struct initialization in C #?
Some code I'm changing makes extensive use of structs to communicate with some factory hardware, loading them into or out of byte arrays.
Here is a simplified example of such a structure.
[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
K_FOO origFoo = new K_FOO();
int and byte are initialized to 0, I assume they are native types, but byte array b3 is * un * initialized - all null values. 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 real structs are huge.
But I noticed something interesting. We have procedures for copying these structures 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 name it ...
K_FOO retFoo = ByteArrayToStructure<K_FOO>(buffer.bytes);
... the resulting structure is returned fully initialized, the bytes in the byte array have all space allocated so that they can be loaded, presumably in a call to PtrToStructure (). This means that .Net "knows" how to initialize such a structure. So is there some way to get .Net to do this for me so I can avoid writing hundreds of lines of explicit initialization code? Thanks in advance!
If you create a BYTE3_TYPE
struct instead of a class, the default constructor (call K_FOO origFoo = new K_FOO();
) will properly initialize the whole thing to zero.
This is also most likely the correct approach if you are trying to match existing specifications and pass that to custom hardware.