首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

C# 含动态数组的结构体封送有关问题

2012-12-19 
C# 含动态数组的结构体封送问题本帖最后由 xillscar 于 2012-06-01 13:43:00 编辑求助 C# 含动态数组的结

C# 含动态数组的结构体封送问题
本帖最后由 xillscar 于 2012-06-01 13:43:00 编辑 求助 C# 含动态数组的结构体封送问题:
结构体代码


//结构体代码
public struct DateSkillList
{
        public byte datatypes;
        public int player_id;

        public ArrayList skill_list;
}

//skill_list包含的是一个Skillslistdate的结构体;

    public struct Skillslistdate
    {
        public int skill_id;
        public int skill_level;
    }


//处理部分
public class bytes
{
    public gobyte()
    {
      DateSkillList msg=new DateSkillList();
      Skillslistdate smg=new Skillslistdate();

      smg.skill_id=10001;
      smg.skill_level=1;

      msg.skill_list.add(smg);

      byte[] buffer=Tool.StructToBytes(msg);
     }
}


//Tool 部分
    public class Tool
    {
        public static byte[] StructToBytes(object obj)
        {
            int size = Marshal.SizeOf(obj);
            byte[] bytes = new byte[size];
            IntPtr structPtr = Marshal.AllocHGlobal(size); //分配结构体大小的内存空间
            Marshal.StructureToPtr(obj, structPtr, false); //将结构体拷到分配好的内存空间
            Marshal.Copy(structPtr, bytes, 0, size);       //从内存空间拷到byte数组
            Marshal.FreeHGlobal(structPtr);                //释放内存空间
            return bytes;
        }

//网络发送部分

NetWorks.AsyncSendMessage(buffers, clns);



在发送到tool转换的时候出错.求各位大神帮助
[最优解释]
StructToBytes 方法
public static byte[] StructToBytes(object obj)
{
    BinaryFormatter bf = new BinaryFormatter();
    using (MemoryStream stream = new MemoryStream())
    {
        bf.Serialize(stream, obj);
        return stream.ToArray();
    }
}

[其他解释]
是不是因为 结构体中不能用ArrayList 这样的动态数组?
如果是.那么我不可能去一条数据就封送一次吧?
这样得多浪费啊?
有没有其他的办法 可以把从数据库取出来的数据 全部按照一定的格式写入到结构体中进行统一封送? 
------其他解决方案--------------------


把 ArrayList 放在结构体了肯定有问题的,关键是读取这封送过去的数据的地方是怎样定义结构体的?
[其他解释]
接收的地方 结构体的格式和发送方的结构体格式完全一致
[其他解释]
你这里只能用序列化的方式获得byte[],因为你的DateSkillList大小未知,里面含有ArrayList这样的不确定大小的数组。
[其他解释]
补充一句 所有的结构体定义的时候都加了
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Unicode), Serializable]
[其他解释]

引用:
接收的地方 结构体的格式和发送方的结构体格式完全一致

接收程序是什么语言?也是C#?
[其他解释]
对的 服务端和客户端都是C#
[其他解释]
补充一句 在封送到Tool的时候 异常提示为 无法计算有意义的大小或偏移量
[其他解释]
反过来
public static object BytesToStruct(byte[] array)
{
    BinaryFormatter bf = new BinaryFormatter();
    using (MemoryStream stream = new MemoryStream(array))
    {
        return bf.Deserialize(stream);
    }
}

[其他解释]
引用:
StructToBytes 方法
C# code
public static byte[] StructToBytes(object obj)
{
    BinaryFormatter bf = new BinaryFormatter();
    using (MemoryStream stream = new MemoryStream())
    {
        bf.Seria……



用 BinaryFormatter  这个的话 我客户端的解析就不对了
[其他解释]
引用:
补充一句 在封送到Tool的时候 异常提示为 无法计算有意义的大小或偏移量

取带有 ArrayList 时的结构体的长度是没有意义的,ArrayList 是引用类型,存放时就是个指针,大小就 4 字节,里面的内容不会算长度的
[其他解释]
那两个结构体,提取出来,放在独立项目中,编译成 dll ,client 和 server 各放一份,引用这个 dll ,读取就没问题了
[其他解释]
引用:
那两个结构体,提取出来,放在独立项目中,编译成 dll ,client 和 server 各放一份,引用这个 dll ,读取就没问题了


你是说我单独的吧 DateSkillList 和 Skillslistdate 编译成dll 做引用?
就不用去修改tool的方法吗?
[其他解释]
引用:
那两个结构体,提取出来,放在独立项目中,编译成 dll ,client 和 server 各放一份,引用这个 dll ,读取就没问题了

请参考WCF的序列化方式,可以做到两处各自定义的。
[其他解释]
感谢大家帮助.我去测试一下
[其他解释]
引用:
引用:

那两个结构体,提取出来,放在独立项目中,编译成 dll ,client 和 server 各放一份,引用这个 dll ,读取就没问题了




你是说我单独的吧 DateSkillList 和 Skillslistdate 编译成dll 做引用?
就不用去修改tool的方法吗?


是编译成dll 做引用,tool 里方法参照 8楼 和 10楼 的。
[其他解释]
楼主的错误是在int size = Marshal.SizeOf(obj);的时候报错,其实也不是完全没辙,可以修改(重新设计)那个方法,让其识别结构体中的数组长度,然后对其进行填充,至于长度,用[MarshalAs(UnmanagedType.ByValArray, SizeConst = XXX)]标识即可。
[其他解释]
引用:
引用:

那两个结构体,提取出来,放在独立项目中,编译成 dll ,client 和 server 各放一份,引用这个 dll ,读取就没问题了

请参考WCF的序列化方式,可以做到两处各自定义的。

我粗略看了下,wcf 是 xml 方式的序列化?
[其他解释]
引用:
引用:
引用:

那两个结构体,提取出来,放在独立项目中,编译成 dll ,client 和 server 各放一份,引用这个 dll ,读取就没问题了


你是说我单独的吧 DateSkillList 和 Skillslistdate 编译成dll 做引用?
就不用去修改tool的方法吗?

是编译成dll 做引用,tool 里方法参照 8楼……

做成 dll 有个好处,修改结构时只要动一处代码
[其他解释]
问题已经解决。感谢大家的帮助
[其他解释]
引用:
StructToBytes 方法
C# code
public static byte[] StructToBytes(object obj)
{
    BinaryFormatter bf = new BinaryFormatter();
    using (MemoryStream stream = new MemoryStream())
    {
        bf.Seria……


在发送的封装的结构体中我定义了一个 byte abyte=0x16 这样的协议编号.

用次方法之后 原来定义的byte类型的协议编号会变成另外的数据.客户端无法正确解析对应的协议

热点排行