110,538
社区成员
发帖
与我相关
我的任务
分享
data[0] = 0x50;
data[1] = 0x43
data[2] = 0x46
data[3] = 0x00;
//width = 512
data[4] = 0x00;
data[5] = 0x02
//height = 1024
data[6] = 0x00;
data[7] = 0x04
public class STF
{
byte[] data1 = new byte[4]
{
80, 67, 70, 0
};
int width { get; set; }
int height { get; set; }
byte[] data2
{
get
{
byte[] data = System.BitConverter.GetBytes(this.width)
.Take(2).Reverse().ToArray();
return data;
}
}
byte[] data3
{
get
{
byte[] data = System.BitConverter.GetBytes(this.height)
.Take(2).Reverse().ToArray();
return data;
}
}
byte[] data4 = new byte[8]
{
0, 1, 2, 3, 4, 5, 6, 7//... ...
};
byte[] data5 = new byte[]
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0//... ...
};
byte[] data6;
//... ...
}
[FieldOffset(0)]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
private byte[] title;
[FieldOffset(4)]
public Int2 data1;
就是data1那里,不管我 title 用上面这种还是就一个 byte,下面的 data1 必须从大于 4 的位置开始,不然就报错。我就纳闷了,真的
比如我改成 3:
问题确定不在 Int2 这个上
[StructLayout(LayoutKind.Explicit, Size = 2)]
public struct Int2
因为我写了个新的结构体,同样的错误
[StructLayout(LayoutKind.Explicit, Size = 10)]
public struct Header
{
[FieldOffset(0)]
private byte header;
[FieldOffset(3)]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public byte[] width;
}
但我改成这样就又没错误了:
[StructLayout(LayoutKind.Explicit, Size = 10)]
public struct Header
{
[FieldOffset(0)]
private byte header;
[FieldOffset(3)]
public byte width;
}
实在不解…… public class STF
{
byte[] data = new byte[1024];
public string Type
{
get { return Encoding.ASCII.GetString(data.Where((x, index) => index < 3).ToArray()); }
}
public int Width
{
get { return BitConverter.ToInt16(data, 4); }
set
{
var v = BitConverter.GetBytes((short)value);
v.CopyTo(data, 4);
}
}
public int Height
{
get { return BitConverter.ToInt16(data, 6); }
set
{
var v = BitConverter.GetBytes((short)value);
v.CopyTo(data, 6);
}
}
public STF(string str)
{
data = Encoding.Default.GetBytes(str);
}
}
var p = new STF("PCF\x00\x00\x02\x00\x04");
Console.WriteLine(p.Type);
Console.WriteLine(p.Width);
Console.WriteLine(p.Height);
p.Width = 300;
p.Height = 600;
Console.WriteLine(p.Type);
Console.WriteLine(p.Width);
Console.WriteLine(p.Height);
Console.ReadKey();
[StructLayout(LayoutKind.Explicit, Size = 1024)]
public struct Header
{
[FieldOffset(0)]
private byte[] data0;//size = 4
[FieldOffset(12)]
private byte[] data3;//size = 4
}
第5到12位补0,16位之后全部为0.
真感觉C#里的结构体就是个败笔 public class STF
{
byte[] data = new byte[1024];
public string Type
{
get { return Encoding.ASCII.GetString(data.Where((x, index) => index < 3).ToArray()); }
}
public int Width
{
get { return BitConverter.ToInt16(data, 4); }
}
public int Height
{
get { return BitConverter.ToInt16(data, 6); }
}
public STF(string str)
{
data = Encoding.Default.GetBytes(str);
}
}
static void Main(string[] args)
{
var p = new STF("PCF\x00\x00\x02\x00\x04");
Console.WriteLine(p.Type);
Console.WriteLine(p.Width);
Console.WriteLine(p.Height);
Console.ReadKey();
}
public class Offset<StructType> where StructType : struct
{
public static object GetValue(StructType item, int offset)
{
try
{
var field = GetFieldAtOffset(offset);
return field.GetValue(item);
}
catch
{
throw;
}
}
public static void SetValue(ref StructType item, int offset, object value)
{
try
{
var field = GetFieldAtOffset(offset);
field.SetValueDirect(__makeref(item), value);
}
catch
{
throw;
}
}
private static FieldInfo GetFieldAtOffset(int offset)
{
try
{
Type structType = typeof(StructType);
var result = structType
.GetFields((BindingFlags)52)
.FirstOrDefault(field =>
{
var attr = field.GetCustomAttributes(
typeof(FieldOffsetAttribute), false)
.FirstOrDefault();
if (attr != null)
{
var offsetAttr = attr as FieldOffsetAttribute;
return offsetAttr.Value == offset;
}
return false;
});
if (result == null)
{
string exc = string.Format("Can not found field at offset {0}, Type is {1}", offset, structType.FullName);
throw new ArgumentException(exc);
}
return result;
}
catch
{
throw;
}
}
}
[StructLayout(LayoutKind.Explicit)]
public struct Header
{
[FieldOffset(0)]
private byte data0;
[FieldOffset(1)]
private byte data1;
[FieldOffset(2)]
private byte data2;
[FieldOffset(3)]
private byte data3;
public byte this[int offset]
{
get
{
object value = Offset<Header>.GetValue(this, offset);
return (byte)value;
}
set
{
Offset<Header>.SetValue(ref this, offset, value);
}
}
}
public class Tester
{
public static void Do1()
{
Header data = new Header();
Console.WriteLine("value of offset 0: {0}", data[0]);
Console.WriteLine("value of offset 0: {0}", data[1]);
Console.WriteLine("value of offset 0: {0}", data[2]);
Console.WriteLine("value of offset 0: {0}", data[3]);
Console.WriteLine("---------------------");
data[0] = 1;
data[1] = 11;
data[2] = 111;
data[3] = 255;
Console.WriteLine("value of offset 0: {0}", data[0]);
Console.WriteLine("value of offset 0: {0}", data[1]);
Console.WriteLine("value of offset 0: {0}", data[2]);
Console.WriteLine("value of offset 0: {0}", data[3]);
}
}
if (index < pos + datai.Length)
{
datai[index - pos] = value;
return;
}
public class STF
{
byte[] data1 = new byte[4] { 80, 67, 70, 0 };
byte[] data2 = new byte[2];
byte[] data3 = new byte[2];
byte[] data4 = new byte[8]
{
0, 1, 2, 3, 4, 5, 6, 7//... ...
};
byte[] data5 = new byte[]
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0//... ...
};
byte[] data6;
//... ...
int width { get { return (int)(data2[0] << 8) + data2[1]; } set { data2[0] = (byte)(value >> 8); data2[1] = (byte)value; } }
int height { get { return (int)(data3[0] << 8) + data3[1]; } set { data3[0] = (byte)(value >> 8); data3[1] = (byte)value; } }
public byte this[int index]
{
get
{
int pos = 0; //0
for (int i = 0; i < 6; i++) //从data1至data6
{
byte[] datai = GetType().GetField("data" + i, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(this) as byte[];
if (datai == null)
continue;
if (index < pos + datai.Length)
return datai[index - pos];
pos += datai.Length;
}
throw new IndexOutOfRangeException();
}
set
{
int pos = 0; //0
for (int i = 0; i < 6; i++) //从data1至data6
{
byte[] datai = GetType().GetField("data" + i, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(this) as byte[];
if (datai == null)
continue;
if (index < pos + datai.Length)
datai[index - pos] = value;
pos += datai.Length;
}
throw new IndexOutOfRangeException();
}
}
}