通用技术 C# 中字节与结构体函数的相互转换

李钚 · 2017年03月03日 · 681 次阅读

C# 使用之字节流结构体的相互转换

本文只提供了相关方法,并没对相关函数做出解释和说明,具体函数的用法还请阅读此文的客官自行查阅百度,百度中会有详细的说明。

一、 结构体转字节流

  1. 结构体的定义:
    1.1 函数结构体定义例子
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct DCCS_APP_PULL_ACK_Stru
    {
    public CSessionHead SessionHead;
    public UInt32 SAddress;

    public UInt32 TAddress;

    public UInt32 UDataLength;

    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2048)]
    public byte[] UData;

    public byte Result;

    }
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct CSessionHead
    {
    public byte Version;

    public UInt16 Handle;

    public UInt16 Tag;

    public UInt32 OpCode;

    }
    1.2 相关说明(这里只简要说明,具体用法请查阅相关资料)
    (1)[StructLayout(LayoutKind.Sequential, Pack = 1)] ,如果不加这句做限制,那么.net 会对结构体布局进行自动调整,导致结构体中变量字节不对应。

  2. 结构体转换成 Byte 函数
    2.1 结构体转换成 Byte 函数
    #region 结构体转换成 Byte
    public static byte[] StructToBytes(object Structname)
    {
    int size = Marshal.SizeOf(Structname);//得到结构体的大小
    IntPtr buffer = Marshal.AllocHGlobal(size); //分配结构体大小的内存空间
    try
    {
    Marshal.StructureToPtr(Structname, buffer, false);//将结构体拷到分配好的内存空间
    byte[] bytes = new byte[size];
    Marshal.Copy(buffer, bytes, 0, size);//从内存空间拷到 byte 数组
    return bytes;//返回 byte 数组
    }
    finally
    {
    Marshal.FreeHGlobal(buffer); //释放内存空间
    }
    }
    #endregion
    2.2 结构体转换成 Byte 函数用法
    APP_DCCS_SUBSCRIBE_IND_Stru Stru = new APP_DCCS_SUBSCRIBE_IND_Stru() ; atc.Send(StructToBytes(Stru));//此为一个发送函数,此处只关注结构体转字节函数的用法即可。

二.字节流转结构体:
public byte[] recvdata;//定义一个字节型的数组
1.字节转结构体函数:
//将 Byte 转换为结构体类型
//括号中的 type 为结构体,bytes 参数为将要进行转换的字节流。关注函数的使用方法,对比即可有所知。
public static object ByteToStruct(byte[] bytes, Type type)

{
int size = Marshal.SizeOf(type);//获取结构体的空间大小
if (size > bytes.Length)
{
return null;
}
//分配结构体内存空间
IntPtr structPtr = Marshal.AllocHGlobal(size);//开辟一个固定大小的内存空间,注意:Marshal.AllocHGlobal(Int32 cb) 中的参数 cb 是分配的字节数
//将 byte 数组拷贝到分配好的内存空间,Int32 类型的两个参数都是用来限定数组的,其中一个限定开始位置,一个限定长度,其中长度是指数组元素的个数,而不是指字节数
Marshal.Copy(bytes, 0, structPtr, size);
//将内存空间转换为目标结构体
object obj = Marshal.PtrToStructure(structPtr, type);
//释放内存空间
Marshal.FreeHGlobal(structPtr);
return obj;
}
2.字节转结构体函数的用法:
DCCS_APP_PULL_ACK_Stru PULL = new DCCS_APP_PULL_ACK_Stru();
PULL = (DCCS_APP_PULL_ACK_Stru) ByteToStruct(atc.recvdata, typeof(DCCS_APP_PULL_ACK_Stru));//typeof 获取子类的类型
3.字节流装入的结构体:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct DCCS_APP_PULL_ACK_Stru
{
public CSessionHead SessionHead;
public UInt32 SAddress;

public UInt32 TAddress;

public UInt32 UDataLength;

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2048)]
public byte[] UData; //定义一个长度 2048 的数组
public byte Result; //定义一个字节变量

}

此文章为技术交流文档。如有不正确之处请指出,互相学习。如需转载,请注明出处。谢谢!
QQ:409393554,邮箱:409393554@qq.com,如有任何疑问请发送邮件留言。

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册