65.9K
CodeProject 正在变化。 阅读更多。
Home

将字节数组转换为包含托管数据的结构

starIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIconemptyStarIcon

1.76/5 (6投票s)

2007年7月4日

CPOL
viewsIcon

65530

downloadIcon

448

如何将托管类型转换为字节数组,以及将字节数组转换为结构体。

引言

我们无法将字节数组直接转换为包含托管类型的结构体。与其以传统方式定义你的结构体,不如使用 [MarshalAs(UnmanagedType.ByValArray, SizeConst = n)] 来定义一个托管类型变量,以便将字节数组转换为结构体,或者将结构体转换为字节数组。

使用代码

在这个示例中,我只使用了一个类。我将创建一个类的实例,然后将该实例转换为字节数组,再将字节数组转换为另一个类的实例。

[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; 
}

转换方法

使用以下两种方法来转换对象

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;
}

注意

请记住不要使用

byte[] buffer = new byte[92];
GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned);
Marshal.StructureToPtr(logFont, h.AddrOfPinnedObject(), false);
h.Free();
return buffer;

因为在多次调用 LogfontToByteArray 方法后,你将会收到来自 COM 的异常。

© . All rights reserved.