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();
- }
- }
- }
通信方面可以参考我之前写的,然后结合此文,来做自己的网络游戏!
更多教程,欢迎关注我的微博 Http://weibo.com/dingxiaowei2013 !
Marshal的简单使用的更多相关文章
- CSharpGL(23)用ComputeShader实现一个简单的ParticleSimulator
CSharpGL(23)用ComputeShader实现一个简单的ParticleSimulator 我还没有用过Compute Shader,所以现在把红宝书里的例子拿来了,加入CSharpGL中. ...
- 用最简单的方式在C#中使用多线程加速耗时的图像处理算法的执行(多核机器)。
图像处理中,有很多算法由于其内在的复杂性是天然的耗时大户,加之图像本身蕴涵的数据量比一般的对象就大,因此,针对这类算法,执行速度的提在很大程度上依赖于硬件的性能,现在流行的CPU都是至少2核的,稍微好 ...
- c# 进程间的通信实现之一简单字符串收发
使用Windows API实现两个进程间(含窗体)的通信在Windows下的两个进程之间通信通常有多种实现方式,在.NET中,有如命名管道.消息队列.共享内存等实现方式,这篇文章要讲的是使用Wi ...
- golang json 包简单分析
首先上代码: func main() { b := true a1, _ := json.Marshal(b) a2, _ := Marshal(b) fmt.Println(string(a1)) ...
- 一个简单的CORBA例子
因为对CORBA分析的需要,这里写一个简单的CORBA例子.从JDK1.2开始,JDK中集成了ORB的实现,本例子使用了JDK1.7,对于JDK1.2+应该都没有问题.这个例子实现一个简单的加减乘除的 ...
- 使用Go开发一个简单的服务器程序
最近有个小项目,需要一个简单的后台程序来支撑,本来想用Nodejs来做,但是由于本人js一直很菜,并且很讨厌callback,虽然我也很喜欢异步模型,但我一直都觉得JS是反人类的.后台就用了go处理, ...
- VSPackge插件系列:简单文本编辑器的实现
相比其它开发环境,VS的好用就不用多说了,尽管VS很人性化,但是针对具体的我们想实现的功能时,会力不从心,也许会有很多现成的插件,但是作为一名程序员,我还是喜欢自己去写一些东西,因为这样能随心所欲的想 ...
- maven 简单实用教程
1. Maven介绍 1.1. 简介 java编写的用于构建系统的自动化工具. 目前版本是2.0.9,注意maven2和maven1有很大区别,阅读第三方文档时需要区分版本. 1.2. Maven资源 ...
- Marshal 类的内存操作的一般功能
Marshal类 提供了一个方法集,这些方法用于分配非托管内存.复制非托管内存块.将托管类型转换为非托管类型,此外还提供了在与非托管代码交互时使用的其他杂项方法. 命名空间:System.Runtim ...
随机推荐
- bzoj 4318 OSU!
期望dp. 考虑问题的简化版:一个数列有n个数,每位有pi的概率为1,否则为0.求以每一位结尾的全为1的后缀长度的期望. 递推就好了. l1[i]=(l1[i-1]+1)*p[i]+0*(1-p[i] ...
- codevs 2988 保留小数 2
2988 保留小数 2 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 白银 Silver 题目描述 Description 这个难度是吸引你点进来的.(其实难度挺 ...
- linux下压缩,解压缩的方法
linux zip命令 zip -r myfile.zip ./* 将当前目录下的所有文件和文件夹全部压缩成myfile.zip文件,-r表示递归压缩子目录下所有文件. 2.unzip unzip - ...
- Java中 NIO与IO的区别
当学习了Java NIO和IO的API后,一个问题马上涌入脑海: 我应该何时使用IO,何时使用NIO呢?在本文中,我会尽量清晰地解析Java NIO和IO的差异.它们的使用场景,以及它们如何影响您的代 ...
- asp rs开启关闭问题
使用rs.close关闭后,可以直接用rs.open来打开数据表:如果用了set rs = nothing 从内存中清除rs对象,再次加载rs对象就需要使用set rs=server.createob ...
- 面试题目——《CC150》数组与字符串
面试题1.1:实现一个算法,确定一个字符串的所有字符是否全都不同.假使不允许使用额外的数据结构,又该如何处理? 注意:ASCII字符共有255个,其中0-127的字符有字符表 第一种解法:是<C ...
- code::blocks编译出错
问题描述: 在windows xp 上编译的cbp项目(已经生成.obj文件),放到fedora上无法顺利编译.(build) collect2:error: ld returned 1 exit s ...
- thinkphp 3.2与phpexcel
thinkphp版本:3.2 1.在http://phpexcel.codeplex.com/下载最新PHPExcel 2.把Classes目录下的文件(PHPExcel.php和PHPExcel文件 ...
- todoList使用教程
网页链接:http://www.cnblogs.com/sunada2005/articles/2663030.html
- ThinkPHP配置简单的mysql读写分离
ThinkPHP内置了分布式数据库的支持,包括主从式数据库的读写分离,但是分布式数据库必须是相同的数据库类型. 配置DB_DEPLOY_TYPE 为1 可以采用分布式数据库支持.如果采用分布式数据库, ...