结构体:
public struct tagCITIZEN_QUERY
{
public int cState;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public char[] czID; //长度为20
}
转换方法:
public byte[] StructToBytes<T>(T obj)
{
int size = Marshal.SizeOf(obj);
byte[] bytes = new byte[1024];
IntPtr arrPtr = Marshal.UnsafeAddrOfPinnedArrayElement(bytes, 0);
Marshal.StructureToPtr(obj, arrPtr, true); //#1异常处
return bytes;
}
调用代码:
tagCITIZEN_QUERY query = new Connection.tagCITIZEN_QUERY();
query.cState = 0;
query.czID = ("12345678901234567890").ToCharArray();byte[] buffer = StructToBytes<tagCITIZEN_QUERY>(query);在#1处出现异常:“未能封送类型,因为嵌入数组实例的长度与布局中声明的长度不匹配”。请问这是什么原因?我用另一个结构体
public struct tagMSG_HEAD
{
public char msgtype;
public short len;
}
时这段代码没有问题,是不是第一个结构体内有 CHAR[] 的原因?
public struct tagCITIZEN_QUERY
{
public int cState;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public char[] czID; //长度为20
}
转换方法:
public byte[] StructToBytes<T>(T obj)
{
int size = Marshal.SizeOf(obj);
byte[] bytes = new byte[1024];
IntPtr arrPtr = Marshal.UnsafeAddrOfPinnedArrayElement(bytes, 0);
Marshal.StructureToPtr(obj, arrPtr, true); //#1异常处
return bytes;
}
调用代码:
tagCITIZEN_QUERY query = new Connection.tagCITIZEN_QUERY();
query.cState = 0;
query.czID = ("12345678901234567890").ToCharArray();byte[] buffer = StructToBytes<tagCITIZEN_QUERY>(query);在#1处出现异常:“未能封送类型,因为嵌入数组实例的长度与布局中声明的长度不匹配”。请问这是什么原因?我用另一个结构体
public struct tagMSG_HEAD
{
public char msgtype;
public short len;
}
时这段代码没有问题,是不是第一个结构体内有 CHAR[] 的原因?
{
LOGIN = 0,
EXIT,
MSG,
CLOSE,
DEFAULT
} public struct TcpPack
{
public Byte[] _data; public CmdType _command;//包类别,枚举,长度2
private UInt16 _length;//记录数据长度 ,2
private UInt16 _ckSum;//校检,长度2
private UInt16 _sequence;//顺序号 长度2 /// <summary>
/// dataLength 数据部分长度
/// </summary>
/// <param name="dataLength"></param>
public TcpPack(UInt16 dataLength)
{
_command = CmdType.DEFAULT;
_ckSum = 0;
_data = new byte[dataLength];
_length = (UInt16)_data.Length;
_sequence = 0;
} /// <summary>
/// 基本构造函数
/// </summary>
/// <param name="command"></param>
/// <param name="checkSum"></param>
/// <param name="data"></param>
public TcpPack(CmdType command, UInt16 checkSum, Byte[] data)
{
_command = command;
_ckSum = checkSum;
_data = new byte[data.Length];
_data = data;
_length = (UInt16)_data.Length;
_sequence = 0;
} /// <summary>
/// Sequence 顺序号
/// </summary>
/// <param name="command"></param>
/// <param name="checkSum"></param>
/// <param name="data"></param>
/// <param name="Sequence"></param>
public TcpPack(CmdType command, UInt16 checkSum, Byte[] data, UInt16 Sequence)
{
_command = command;
_ckSum = checkSum;
_data = new byte[data.Length];
_data = data;
_length = (UInt16)_data.Length;
_sequence = Sequence;
}
/// <summary>
/// 序列化包体
/// </summary>
/// <param name="buffer"></param>
/// <returns></returns>
public int ConvertToByte(Byte[] buffer)
{
Byte[] b_command = BitConverter.GetBytes((UInt16)_command);
Byte[] b_ckSum = BitConverter.GetBytes(_ckSum);
Byte[] b_length = BitConverter.GetBytes(_length);
Byte[] b_sequence = BitConverter.GetBytes(_sequence);
int index;
index = 0; Array.Copy(b_command, 0, buffer, index, b_command.Length);
index += b_command.Length; Array.Copy(b_ckSum, 0, buffer, index, b_ckSum.Length);
index += b_ckSum.Length; Array.Copy(b_length, 0, buffer, index, b_length.Length);
index += b_length.Length; ; Array.Copy(b_sequence, 0, buffer, index, b_sequence.Length);
index += b_sequence.Length; Array.Copy(_data, 0, buffer, index, _data.Length);
index += _data.Length;
return index;
} /// <summary>
/// 反序列化包头
/// </summary>
/// <param name="buffer"></param>
/// <returns></returns>
public TcpPack ConvertToStruct(Byte[] buffer)
{
_command = (CmdType)BitConverter.ToUInt16(buffer, 0);
_ckSum = BitConverter.ToUInt16(buffer, 2);
_length = BitConverter.ToUInt16(buffer, 4);
_sequence = BitConverter.ToUInt16(buffer, 6);
_data = new Byte[_length];
return this;
} public UInt16 CheckSum
{
get
{
return _ckSum;
}
set
{
_ckSum = value; }
} public static UInt16 HeadLength
{
get
{
return 8;
}
} public static UInt16 MaxDataLength
{
get
{
return 1024;
}
}
public UInt16 GetSequence
{
get
{
return _sequence;
}
} public UInt16 GetDataLength
{
get
{
return _length;
}
}
}
[Serializable]//标记为可序列化
public struct tagCITIZEN_QUERY
{
public int cState;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public char[] czID; //长度为20
}
public byte[] StructToBytes<T>(T obj)
{
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream memStream = new MemoryStream();
formatter.Serialize(memStream, obj);
byte[] bytes = memStream.GetBuffer();
memStream.Close();
return bytes;
}
先
byte czIDbak= new byte[20];for(int i =0;i<20;i++){
czIDbak[i]=0x00;
}然后你再复制数组
Array.Copy(........这样才可以转换数组
StructToBytes<T>(T obj)....这样才可以发送
因为我现在的项目中做的和你说类似的事
没有出现问题? 难道是我系统VISTA的原因?
记住这里不能直接转,你要保证数组大小一致,("12345678901234567890")字符串转byte[]不够长的要用空白填充
这样就不得数组越界,这是问题的所在
{
byte[] ToBytes();
}如果真的想用一个静态方法来把所有的可能的类型都转化成byte[],估计要用点反射。
char[] czID 长度定成20后,实际数据长度不足20,又没有自动补位.....也谢谢各位~~~
结贴了~~