Unity与c++数据通信时 结构体转字节数组

11 篇文章 0 订阅

最近遇到需求和MFC的 c++的服务器进行通信,但是c#直接转换结构体有些困难,好在在大佬的博客里找到了解决方法

本文参考大佬牛逼,如果已经参考过这篇文章,不建议继续阅读本文


c++与c#不通数据类型字节长度的对比
首先,最大的问题是,c++的数据类型和c#的数据类型所占的内存空间不一定一样长,此处为常用的数据类型的字节长度对比

c++说明c#说明
bool1字节bool1字节
int4字节int4字节
char1字节char2字节
float4字节float4字节
double8字节double8字节
byte1字节byte1字节

c++中
unsigned 表示无符号
unsigned int 表示无符号整数,4字节,单一个unsigned为unsigned int的缩写
short [int]/signed short[int] 有符号短整数 2 字节 unsigned short无符号短整数 2字节
long[int] 有符号长整形 4字节 范围和int相同 unsinged long[int] 无符号长整形 4字节
long long 8字节
long double 8字节
wchar宽字符型char 2字节,实际上就是c#的char

c#中单数据转换 (注意这和结构体转换字节数组没有关系,仅作为记录)

byte[] buff = BitConverter.GetBytes('好');

这种方法只能转化单个字段,也不能转换string,并不实用
C#中结构体转字节数组
命名空间

using System.Runtime.InteropServices;

结构体的样式

[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct DETPARAM
{
    public int CommandType;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)]
    public string radioCode;
    public double midFrequency;
    public byte Major_minor;
}

需要注意的是编码格式为Ansi,转换出来为16进制编码 ,
pack=1 每个字符占一个字节 ,如果c++中规定每个字符占两个字节,pack =2

结构体转字节数组的方法

     <summary>
    /// 结构体转byte数组
    /// </summary>
    /// <param name="structObj">要转换的结构体</param>
    /// <returns>转换后的byte数组</returns>
    public static byte[] StructToBytes(object structObj)
    {
        //得到结构体的大小
        int size = Marshal.SizeOf(structObj);
        //创建byte数组
        byte[] bytes = new byte[size];
        //分配结构体大小的内存空间
        IntPtr structPtr = Marshal.AllocHGlobal(size);
        //将结构体拷到分配好的内存空间
        Marshal.StructureToPtr(structObj, structPtr, false);
        //从内存空间拷到byte数组
        Marshal.Copy(structPtr, bytes, 0, size);
        //释放内存空间
        Marshal.FreeHGlobal(structPtr);
        //返回byte数组
        return bytes;
    }

字节数组转结构体的方法

    /// <summary>
    /// byte数组转结构体
    /// </summary>
    /// <param name="bytes">byte数组</param>
    /// <param name="type">结构体类型</param>
    /// <returns>转换后的结构体</returns>
    public static object BytesToStuct(byte[] bytes, Type type)
    {
        //得到结构体的大小
        int size = Marshal.SizeOf(type);
        //byte数组长度小于结构体的大小
        if (size > bytes.Length)
        {
            //返回空
            return null;
        }
        //分配结构体大小的内存空间
        IntPtr structPtr = Marshal.AllocHGlobal(size);
        //将byte数组拷到分配好的内存空间
        Marshal.Copy(bytes, 0, structPtr, size);
        //将内存空间转换为目标结构体
        object obj = Marshal.PtrToStructure(structPtr, type);
        //释放内存空间
        Marshal.FreeHGlobal(structPtr);
        //返回结构体
        return obj;
    }

调用转字节数组的方法

         //声明结构体
         DETPARAM dep;
         //填充数据
         dep.CommandType = 10;
         dep.radioCode = "49";
         dep.midFrequency = 1.0;       
         dep.Major_minor = 0;
         //转换为字节数组
         Byte[] recv = Tool_My.StructToBytes(dep);
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值