加载中
加载中
表情图片
评为精选
鼓励
加载中...
分享
加载中...
文件下载
加载中...
修改排序
加载中...
C#中读写byte[]数组中的结构体
acmilan2016/06/08软件综合 IP:四川

C++中,可以通过指针强制转换来读取char[]中的结构体,但是到了C#中,这一招行不通了。

通过查找资料发现,在C#中可以有多种读取byte[]中的结构体的方法,但是我感觉最可靠的还是使用BitConverter:

  • 从byte[]读取字段,使用field = BitConverter.ToXXX(bytes, offset)实现。
  • 向byte[]写入字段,使用BitConverter.GetBytes(field).CopyTo(bytes, offset)实现。

注意定长字符串不能用BitConverter.ToString,它是用来返回16进制表示的。对于定长字符串来说:

  • 从byte[]读取定长字符串,可以这样实现:
Other
field = Encoding.XXX.GetString(bytes, offset, length).Split('\0')[0];
  • 向byte[]写入定长字符串就麻烦点了,因为需要控制缓冲区长度:
Other
byte[] data = new byte[length]; Encoding.XXX.GetBytes(field).CopyTo(data, 0); data.CopyTo(bytes, offset);

示例代码如下:

Other
public enum BICompression : uint { BI_RGB = 0, // 不压缩 BI_RLE8 = 1, // 8位运行长度编码 BI_RLE4 = 2, // 4位运行长度编码 BI_BITFIELDS = 3 // 使用颜色位屏蔽 } public struct BitmapInfoHeader { public uint biSize; // 结构的大小>=40 public int biWidth; // 图像宽度(像素) public int biHeight; // 图像高度(像素) public ushort biPlanes; // = 1 public ushort biBitCount; // 每像素的位数(1,4,8,16,24,32) public BICompression biCompression; // 压缩代码 public uint biSizeImage; // 图像的字节数 public int biXPelsPerMeter; // 横向分辨率 public int biYPelsPerMeter; // 纵向分辨率 public uint biClrUsed; // 使用的颜色数 public uint biClrImportant; // 重要颜色数 public BitmapInfoHeader(byte[] src, int off) { biSize = BitConverter.ToUInt32(src, off); biWidth = BitConverter.ToInt32(src, off + 4); biHeight = BitConverter.ToInt32(src, off + 8); biPlanes = BitConverter.ToUInt16(src, off + 12); biBitCount = BitConverter.ToUInt16(src, off + 14); biCompression = (BICompression)BitConverter.ToUInt32(src, off + 16); biSizeImage = BitConverter.ToUInt32(src, off + 20); biXPelsPerMeter = BitConverter.ToInt32(src, off + 24); biYPelsPerMeter = BitConverter.ToInt32(src, off + 28); biClrUsed = BitConverter.ToUInt32(src, off + 32); biClrImportant = BitConverter.ToUInt32(src, off + 36); } public void WriteBytes(byte[] dst, int off) { BitConverter.GetBytes(biSize).CopyTo(dst, off); BitConverter.GetBytes(biWidth).CopyTo(dst, off + 4); BitConverter.GetBytes(biHeight).CopyTo(dst, off + 8); BitConverter.GetBytes(biPlanes).CopyTo(dst, off + 12); BitConverter.GetBytes(biBitCount).CopyTo(dst, off + 14); BitConverter.GetBytes((uint)biCompression).CopyTo(dst, off + 16); BitConverter.GetBytes(biSizeImage).CopyTo(dst, off + 20); BitConverter.GetBytes(biXPelsPerMeter).CopyTo(dst, off + 24); BitConverter.GetBytes(biYPelsPerMeter).CopyTo(dst, off + 28); BitConverter.GetBytes(biClrUsed).CopyTo(dst, off + 32); BitConverter.GetBytes(biClrImportant).CopyTo(dst, off + 36); } }

[修改于 8年11个月前 - 2016/06/09 10:34:28]

来自:计算机科学 / 软件综合
4
新版本公告
~~空空如也
acmilan 作者
8年11个月前 修改于 8年11个月前 IP:四川
821141

对于和一般的WinAPI交互来说,没必要这么麻烦,可以使用StructLayout和MarshalAs解决:

Other
using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; namespace ConsoleApplication5 { class Program { [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct RtlOSVersionInfoExW { public uint dwOSVersionInfoSize; public uint dwMajorVersion; public uint dwMinorVersion; public uint dwBuildNumber; public uint dwPlatformId; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string szCSDVersion; public ushort wServicePackMajor; public ushort wServicePackMinor; public ushort wSuiteMask; public byte wProductType; public byte wReserved; } [DllImport("ntdll.dll")] public static extern bool RtlGetVersion(ref RtlOSVersionInfoExW osver); static void Main(string[] args) { RtlOSVersionInfoExW osvex = new RtlOSVersionInfoExW(); osvex.dwOSVersionInfoSize = (uint)Marshal.SizeOf(osvex); RtlGetVersion(ref osvex); Console.WriteLine(osvex.dwMajorVersion); Console.WriteLine(osvex.dwMinorVersion); Console.WriteLine(osvex.dwBuildNumber); Console.WriteLine(osvex.dwPlatformId); Console.WriteLine(osvex.szCSDVersion); Console.WriteLine(osvex.wServicePackMajor); Console.WriteLine(osvex.wServicePackMinor); Console.WriteLine(osvex.wSuiteMask); Console.WriteLine(osvex.wProductType); Console.WriteLine(osvex.wReserved); } } }
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
acmilan作者
8年11个月前 IP:四川
821250

引用 张静茹 : /// <summary> /// 结构体 值类型转byte数组 /// BitConverter /// </summary> ///……

写个算法也要用到互操作性,总感觉不爽。。。

引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论

想参与大家的讨论?现在就 登录 或者 注册

所属专业
所属分类
上级专业
同级专业
acmilan
进士 学者 笔友
文章
461
回复
2934
学术分
4
2009/05/30注册,6年3个月前活动
暂无简介
主体类型:个人
所属领域:无
认证方式:邮箱
IP归属地:未同步
插入公式
评论控制
加载中...
文号:{{pid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

笔记
{{note.content}}
{{n.user.username}}
{{fromNow(n.toc)}} {{n.status === noteStatus.disabled ? "已屏蔽" : ""}} {{n.status === noteStatus.unknown ? "正在审核" : ""}} {{n.status === noteStatus.deleted ? '已删除' : ''}}
  • 编辑
  • 删除
  • {{n.status === 'disabled' ? "解除屏蔽" : "屏蔽" }}
我也是有底线的