[.NET2.0]Marshal类的使用

终于从北京回上海了,第一次听unity开发者大会,感觉讲的都是一些Unity 5新功能的介绍,其实主要还是要靠自己去摸索那些新的功能,主要就是添加了新的GUI系统,貌似集成了NGUI到Unity中,取名UGUI,还有就是集成了新的声音系统和新的动画系统,我感觉新的声音系统还是比较强大的,期待unity5的问世。大会上介绍了一些常用的插件以及Test Tools的使用,总体而言都是一些展望未来性质多点哈。希望Unity越来越强大!

废话不多说,接下来介绍一下客户端服务器通讯常用的一种方法——Marshal类,这个类是.NETFramework2.0中的类,所以我们能够将其用于Unity中。与这个类类似的还有litjson等,可能是为了节省字节空间,Marshal类只仅仅将值进行打包成bytes流,而json还包含前面的key值。当然你也可以选择json的方式,我这里仅仅介绍Marshal类的使用。点击进入MSDN中Marshal类的介绍和使用

在这之前首先要了解一下关于字节序的大端和小端模式,点击阅读,可以参考这篇文章了解一下。这里我用的window的机器是小端模式。

效果图

代码

Model类:

using System;
using System.Runtime.InteropServices;

namespace mershal
{
    class Model
    {
        [Serializable]
        [StructLayout(LayoutKind.Sequential,Pack = 1)]//按1字节对齐
        public struct Student
        {
            public UInt32 id;
            [MarshalAsAttribute(UnmanagedType.ByValTStr,SizeConst=20)]
            public string name;//姓名
        }
    }

    class Method
    {
        /// <summary>
        /// 结构体转bytes
        /// </summary>
        /// <param name="structObj">结构体</param>
        /// <param name="decCount">默认0,不截取</param>
        /// <returns></returns>
        public static byte[] StructToBytes(object structObj, Int32 decCount)
        {
            Int32 size = Marshal.SizeOf(structObj);
            //开辟空间
            IntPtr buffer = Marshal.AllocHGlobal(size);
            try
            {
                Marshal.StructureToPtr(structObj, buffer, false);
                byte[] bytes = new byte[size - decCount];
                Marshal.Copy(buffer, bytes, 0, size - decCount);
                return bytes;
            }
            finally
            {
                //释放空间
                Marshal.FreeHGlobal(buffer);
            }
        }
        /// <summary>
        /// byte转结构体
        /// </summary>
        /// <param name="bytes">byte数组</param>
        /// <param name="type">结构体类型</param>
        /// <returns></returns>
        public static object ByteToStruct(byte[] bytes, Type type)
        {
            Int32 size = Marshal.SizeOf(type);
            //byte数组长度小于结构体大小
            if (size > bytes.Length)
            {
                //返回空
                return null;
            }
            //分配结构大小的内存空间
            IntPtr structPtr = Marshal.AllocHGlobal(size);
            //将byte数组拷贝到分配好的内存空间
            Marshal.Copy(bytes, 0, structPtr, size);
            //将内存空间转换成目标结构
            object obj = Marshal.PtrToStructure(structPtr, type);
            //释放内存空间
            Marshal.FreeHGlobal(structPtr);
            //返回结构
            return obj;
        }
    }
}

主函数:

using System;

namespace mershal
{
    class Program
    {
        static void Main(string[] args)
        {
            //实例化
            Model.Student stu1 = new Model.Student();
            stu1.id = 1;
            stu1.name = "丁小未";
            //打包
            byte[] byte1 = Method.StructToBytes(stu1,0);
            Console.WriteLine("字节长度:"+byte1.Length);
            //解析
            Model.Student stu =  (Model.Student)Method.ByteToStruct(byte1, typeof(Model.Student));
            Console.WriteLine("\n输出的学生信息\nid:" + stu.id+"\nname:"+stu.name);
            Console.Read();
        }
    }
}

通信方面可以参考我之前写的,然后结合此文,来做自己的网络游戏!

点击阅读

更多教程,欢迎关注我的微博

时间: 2024-09-14 06:51:28

[.NET2.0]Marshal类的使用的相关文章

ASP.NET2.0中的ClientScriptManager 类用法

asp.net|client ASP.NET2.0中的ClientScriptManager 类用法-如何添加客户端事件 在ASP.NET2.0中,ClientScriptManager 类通过键 String 和 Type 唯一地标识脚本.具有相同的键和类型的脚本被视为重复脚本.因此,我们可以使用脚本类型来避免混淆可能用在页中的来自不同用户控件的相似脚本. <html>  <head>    <title>ClientScriptManager Example<

我的数据访问类(第二版)—— for .net2.0 (一)

asp.net2.0已经出来好久了,由于许多的原因一直没有使用,一个月前才开始使用VS2005写东西. 这一个月里又重新学习了一下基础知识,比如多态.接口了什么的. 既然已经到了2.0了嘛,那么以前的数据访问的方式要不要变一下呢?简单看了一下,感觉还是我的那种方式好,至少时我已经用习惯了.那么用.net2.0的方法重写一遍吧. 看了一下Framework 2.0的代码,发现一个问题.虽然表面上ADO.NET的使用没有什么变化(加了一些功能,原来由的功能没有变),但是内部实现有比较大的变化,原来的

MagicAjax.net2.0 框架特殊字符的处理

ajax        发现这么多人在用这个MagicAjax框架,但是没有人发现这个框架对特殊字符html标记未处理.回调后对页面中特殊字符显示问题,比如特别符号 ?; (其中 ? 代表 ISO 8859-1 的编码) < < > > & & " "  等,当一本框值为<100公的的猪,其中有一小于号 (<),而&符号又被译出(& amp),最后文本框的值将会变成& amp lt,这样几个字符.有如下两种解决

基于ASP.NET2.0的非HttpModule山寨版MVC框架的实现

在ASP.Net MVC框架中是使用地址拦截的,虽然很好用,但是装起来太大了,配置也麻烦.本文通过代码实践,在ASP.Net2.0框架下实现一套简易的MVC框架.MVC框架难于构建的地方在于Controller与View的分离以及分离后数据可以方便地传输.为了保持代码的简洁,将使用ashx文件作为Controller,用aspx页面作为View. 讲起来比较费劲,把项目文件放上来,而下面只作一个简单的说明.项目是VS2008的项目,大小15K. 下载地址:DotNetMVC.rar 首先构建一个

Asp.Net2.0技巧(续)

1.  在开发web控件时,如果控件必须放在服务器端的form内,可以通过Page.VerifyRenderingInServerForm(Control) 方法来保证. 2.  使用Control类的ResolveClientUrl(string)方法可以将类似"~/abc/ab.aspx"这样的路径转换为正确的url路径,这在.Net1.0中是一个内部方法,而在2.0中是公开的方法 3.  Button控件有两个事件,分别是OnClick和OnCommand,在点击button之后

ADO.NET2.0的十大最新特性

ado                                                                          ADO.NET2.0的十大最新特性         这篇文章概述了.NET Framework 2.0里的ADO.NET2.0的最新特性.在以下叙述中将附带一些简单的例子来讨论这些特性的细节. 以下便是ADO.NET新增的特性: 1. 批量复制操作(Bulk Copy Operation) 将数据从一个数据源批量复制到另一个数据源是ADO.NE

net2.0如何修改用户密码的解决

解决 在net2.0里MemebershipUser类有个ChangePassword的方法,但是他有两个参数,旧密码和新密码,但是问题来了啊,我怎么知道用户的旧密码啊如果我做为管理员要修改用户密码的话,解决办法如下,先给用户ResetPassword代码: MembershipUser user = Membership.GetUser(txtFindUserName.Text.ToString().Trim());        user.UnlockUser();        strin

数据绑定控件再ASP.NET1.X和ASP.NET2.0的区别

asp.net|控件|区别|数据 数据绑定在ASP.NET2.0里进一步得到简化,绑定控件的基类来自于BaseDataBoundControl,你可以到http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.basedataboundcontrol_members(VS.80).aspx查看该类如果你查看该类的成员,请注意下面两个属性和方法 virtual object DataSource  { get; set;

ASP.NET2.0 WebRource,开发微调按钮控件

asp.net|web|按钮|控件 现在.有许多开发人员已经在使用ASP.NET2.0的WebResource的功能了.WebResource允许我们嵌入资源到程序集中.包括图像,文本等. 在介绍WebResource就不得不介绍一下WebResource.axd,我们来看一下 script language="javascript"     src="WebResource.axd?a=s&r=WebUIValidation.js&t=63194436284