Introduction
We can't convert a bytes array to a structure which contains managed type. Instead of defining your structure the traditional way, you can use [MarshalAs(UnmanagedType.ByValArray, SizeConst = n)]
to define a managed type variable in order to convert a bytes array to a structure or convert a structure to a bytes array.
Using the code
In this sample, I have used only one class. I'm going to create an instance of the class, then convert the instance to a bytes array, and convert the bytes array to another instance of the class:
[StructLayout(LayoutKind.Sequential)]
public class LogFont
{
int lfHeight;
int lfWidth;
int lfEscapement;
int lfOrientation;
int lfWeight;
byte lfItalic;
byte lfUnderline;
byte lfStrikeOut;
byte lfCharSet;
byte lfOutPrecision;
byte lfClipPrecision;
byte lfQuality;
byte lfPitchAndFamily;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
byte[] lfFaceName;
}
Converting Methods
Use the two methods shown below to convert objects:
public static LogFont GetLogFontFromBff(byte[] bff)
{
LogFont logFont = new LogFont();
IntPtr ptPoit = Marshal.AllocHGlobal(92);
Marshal.Copy(bff, 0, ptPoit, 92);
logFont = (LogFont)Marshal.PtrToStructure(ptPoit, typeof(LogFont));
Marshal.FreeHGlobal(ptPoit);
return logFont;
}
public static byte[] LogfontToByteArray(LogFont logFont)
{
IntPtr ptPoint = Marshal.AllocHGlobal(92);
Marshal.StructureToPtr(logFont, ptPoint, true);
byte[] bff = new byte[92];
Marshal.Copy(ptPoint, bff, 0, 92);
Marshal.FreeHGlobal(ptPoint);
return bff;
}
Note
Let's remember not to use:
byte[] buffer = new byte[92];
GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned);
Marshal.StructureToPtr(logFont, h.AddrOfPinnedObject(), false);
h.Free();
return buffer;
because you'll have an exception from COM after calling the LogfontToByteArray
method too many times.