C# 通讯时字节流和结构体互转

本文详细介绍了如何使用C#将结构体转换为字节流,并通过示例展示了在实际场景中的应用。重点在于结构体转换过程的实现细节,包括内存布局和异常处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//Author:smilelance

//From:http://blog.youkuaiyun.com/smilelance

//转换C#代码:

using System.Runtime.InteropServices;

//结构体转换成字节流

public static byte[] StructToBytes<T>(T obj)
    {
int size = Marshal.SizeOf(typeof(T));
   IntPtr bufferPtr = Marshal.AllocHGlobal(size);
try   
{
       Marshal.StructureToPtr(obj, bufferPtr, false);
       byte[] bytes = new byte[size];
       Marshal.Copy(bufferPtr, bytes, 0, size);

       return bytes;
}
        catch(Exception ex)
        {
            throw new Exception("Error in StructToBytes ! " + ex.Message);
        }
finally   
{   
  Marshal.FreeHGlobal(bufferPtr);   
}  
    }


//字节流转换成结构体

    public static T BytesToStruct<T>(byte[] bytes, int startIndex = 0)
    {
        if (bytes == null) return default(T);
        if (bytes.Length <= 0) return default(T);
int objLength = Marshal.SizeOf(typeof(T));
        IntPtr bufferPtr = Marshal.AllocHGlobal(objLength);
        try//struct_bytes转换
        {
            Marshal.Copy(bytes, startIndex, bufferPtr, objLength);
            return (T)Marshal.PtrToStructure(bufferPtr, typeof(T));
        }
        catch(Exception ex)
        {
            throw new Exception("Error in BytesToStruct ! " + ex.Message);
        }
        finally
        {
            Marshal.FreeHGlobal(bufferPtr);
        }
    }


[StructLayout(LayoutKind.Sequential, Pack=1)]  //变量在内存中的对齐方式 ,每个结构体都需要
public struct LolMsgHeader
{
public ushort wMsgLen;
public byte    header_ver;
public ushort uAction; //动作行为
public uint  dwUid; //用户ID
public uint dwSeq; //包的序列号
public uint  dwPid; //当前服务ID

};


public struct LOLMoveMsg
{
[MarshalAs(UnmanagedType.SysUInt, SizeConst = LOLMsgConst.MASK_LEN)]
public WORD        mask;                   // 掩码
[MarshalAs(UnmanagedType.ByValArray, SizeConst = LOLMsgConst.NAME_LEN)]
public byte[] szName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = LOLMsgConst.NAME_LEN)]
public string targetName;//目的对象
public short x;
public short y;
public byte byReached;//到达目的地,未到达0,到达1
};


//注意,之前遇到过在ios真机上运行不起来的bug,在android真机和ios模拟器上都是OK的问题,

后来把所有的ByValArray改成ByValTStr解决了这个问题。

如果有可能,建议不要用数组,全部都用基本类型。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值