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!
source to share
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.
source to share