将类实例值转换为字节列表的其他好方法,只是原始数据? [英] Other good way to convert class instance value to byte List, just raw data?
本文介绍了将类实例值转换为字节列表的其他好方法,只是原始数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
亲爱的所有,
如果我们想将类实例的值保存到字节列表中。只是原始数据(如果使用了序列化,将会有一些标记。我之前使用过这种方式,但它不是我想要的)
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屋!
查看全文