将类实例值转换为字节列表的其他好方法,只是原始数据? [英] Other good way to convert class instance value to byte List, just raw data?

查看:97
本文介绍了将类实例值转换为字节列表的其他好方法,只是原始数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

亲爱的所有,

如果我们想将类实例的值保存到字节列表中。只是原始数据(如果使用了序列化,将会有一些标记。我之前使用过这种方式,但它不是我想要的)

If we want to save the class instance's value to byte list. Just raw data(there will be some tag if Serialization is used. I have used this way before but it is not what I want)

我能想出的唯一方法是转换每个属性在类实例中手动如下,结果也是正确的。

The only way I can figure out is convert each property in class instance manually like below and the result is also correct.

还有其他更好的方式,更具有编程性吗?

谢谢和敬意,

E-John

namespace TestWinFormObjectToByteList
{
    [StructLayout(LayoutKind.Sequential)]
    public class TxDataStruct
    {
        public UInt32 ID;
        public ushort Number;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
        public byte[] Name = new byte[20];
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20 * 32)]
        public byte[,] NameBitMap = new byte[20, 32];
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
        public byte[] Attribute = new byte[6];
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public byte[] Company = new byte[8];
    }

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            TxDataStruct tx = new TxDataStruct();

            // test object pattern
            tx.ID = 0x12345678;
            tx.Number = 100;
            byte[] strByte = Encoding.ASCII.GetBytes("tx1");
            int size = Math.Min(strByte.Length, tx.Name.Length);
            for (int i = 0; i < size; i++)
            {
                tx.Name[i] = strByte[i];
            }

            for (int i = 0; i < tx.NameBitMap.GetLength(0); i++)
            {
                for (int j = 0; j < tx.NameBitMap.GetLength(1); j++)
                {
                    tx.NameBitMap[i, j] = (byte)(i);
                }
            }
            for (int i = 0; i < tx.Attribute.Length; i++)
            {
                tx.Attribute[i] = (byte)(i + 0x0a);
            }
            strByte = Encoding.ASCII.GetBytes("VeryWell");
            size = Math.Min(strByte.Length, tx.Name.Length);
            for (int i = 0; i < size; i++)
            {
                tx.Company[i] = strByte[i];
            }

            // convert class object to byte array
            List<byte> listByte = new List<byte>();

            listByte.Clear();

            // MSB
            listByte.Add((byte)((tx.ID >> 24) & 0xff));
            listByte.Add((byte)((tx.ID >> 16) & 0xff));
            listByte.Add((byte)((tx.ID >> 8) & 0xff));
            listByte.Add((byte)((tx.ID >> 0) & 0xff));

            listByte.Add((byte)((tx.Number >> 8) & 0xff));
            listByte.Add((byte)((tx.Number >> 0) & 0xff));

            for (int i = 0; i < tx.Name.Length; i++)
            {
                listByte.Add(tx.Name[i]);
            }

            for (int i = 0; i < tx.NameBitMap.GetLength(0); i++)
            {
                for (int j = 0; j < tx.NameBitMap.GetLength(1); j++)
                {
                    listByte.Add(tx.NameBitMap[i, j]);
                }
            }

            for (int i = 0; i < tx.Attribute.Length; i++)
            {
                listByte.Add(tx.Attribute[i]);
            }

            for (int i = 0; i < tx.Company.Length; i++)
            {
                listByte.Add(tx.Company[i]);
            }

            ByteViewer byteViewer = new ByteViewer();
            // save to file then load file to bv
            byteViewer.SetBytes(listByte.ToArray());

            // get current directory
            string byteListFileName = @"\byteList.bin";
            string path = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            path += byteListFileName;

            // Add create directory if it doesn't exist
            bool exists = System.IO.Directory.Exists(Path.GetDirectoryName(path));
            if (!exists)
                System.IO.Directory.CreateDirectory(Path.GetDirectoryName(path));

            if (File.Exists(path))
            {
                File.Delete(path);
            }

            // save to file
            byteViewer.SaveToFile(path);

            // load from file
            byteViewer.SetFile(path);

            string msg = "Save file to" + path + "is complete";
            MessageBox.Show(msg);
        }
    }
}

推荐答案

尝试两种方法:

Try two methods:

byte[] bytes = new byte[Marshal.SizeOf( tx )];
GCHandle h = GCHandle.Alloc( bytes, GCHandleType.Pinned );
Marshal.StructureToPtr( tx, h.AddrOfPinnedObject(), false );
h.Free();

byte[] bytes = new byte[Marshal.SizeOf( tx )];
IntPtr m = Marshal.AllocHGlobal( Marshal.SizeOf( tx ) );
Marshal.StructureToPtr( tx, m, false );
Marshal.Copy( m, bytes, 0, bytes.Length );
Marshal.FreeHGlobal( m );


这篇关于将类实例值转换为字节列表的其他好方法,只是原始数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆