65.9K
CodeProject is changing. Read more.
Home

Convert a byte array to a struct which contains managed data

starIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIconemptyStarIcon

1.76/5 (6 votes)

Jul 4, 2007

CPOL
viewsIcon

65075

downloadIcon

437

How to convert a managed type to a byte array and a byte array to a struct.

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
{
    /// <summary>
    /// 4 bytes
    /// </summary>
    int lfHeight;

    /// <summary>
    /// 4 bytes
    /// </summary>
    int lfWidth;

    /// <summary>
    /// 4 bytes
    /// </summary>
    int lfEscapement;

    /// <summary>
    /// 4 bytes
    /// </summary>
    int lfOrientation;

    /// <summary>
    /// 4 bytes
    /// </summary>
    int lfWeight;

    /// <summary>
    /// 1 byte
    /// </summary>
    byte lfItalic;

    /// <summary>
    /// 1 byte
    /// </summary>
    byte lfUnderline;

    /// <summary>
    /// 1 byte
    /// </summary>
    byte lfStrikeOut;

    /// <summary>
    /// 1 byte
    /// </summary>
    byte lfCharSet;

    /// <summary>
    /// 1 byte
    /// </summary>
    byte lfOutPrecision;

    /// <summary>
    /// 1 byte
    /// </summary>
    byte lfClipPrecision;

    /// <summary>
    /// 1 byte
    /// </summary>
    byte lfQuality;

    /// <summary>
    /// 1 byte
    /// </summary>
    byte lfPitchAndFamily;

    /// <summary>
    /// 64 bytes
    /// </summary>
    [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.