之前游戏为了解决在ios自动更新的问题,想到使用了将游戏代码打包成dll,使用反射加载执行的办法。办法想好了以后,一直没有做测试。上周不知道什么原因,终于有人去测试了,结果发现报错了。我当时觉得有点意外。虽说网上有人说ios上不能使用.net的反射模块,但是后来我仔细研究过这个问题,发现技术上应该是可行的。因为unity在使用C#作为脚本时,底层是使用的是mono。而使用mono的话,在ios平台上面,底层就应该是使用的Xamarin.iOS。它对于ios的限制主要在于它使用了AOT编译,而不是传统的JIT,也就是说IL代码在编译时,就被翻译成对应平台的机器码,而不是如JIT一样,在运行时动态翻译。其实大部分嵌入式平台都不会对JIT进行支持,主要是几个方面原因的考虑,(1)加快启动程序时间;(2)执行效率;(3)节约内存。既然是使用AOT编译,那么它对反射的限制应该主要是限制部分依赖JIT的功能,因此这个问题得核心不是反射的问题,而是JIT与AOT区别的问题。而我们使用反射只是在dll中查找一个已知类,这个应该是可以静态编译的,对JIT没有要求。

  带着疑问,我帮忙查看了下报错的日志。结果才发现不是加载dll的地方报错了,而是在之后的代码里,protobuf-net的代码。这个发现说明了两个问题:(1)第一是dll里的入口函数已经进入了,因为报错的位置在这个之后很远的地方。这说明了之前的思路是没有问题。(2)第二protobuf-net在ios上面报错的原因还是和前面说的AOT编译限制有关。因为它使用了反射中对JIT有依赖的功能。

  接下来就是解决protobuf-net的问题。其实之前早有人遇到了这个问题,protobuf-net作者因此提供了一个procompile的模块来解决它。大概的思路是(1)将proto文件解析出来的cs文件编译到一个独立的dll中;(2)使用precompile模块对这个新的dll进行处理,生成一个新的序列化dll,我个人觉得这个步骤主要是在这个序列化dll中记录消息类的描述信息,以便后面序列化,反序列化时不需要对JIT依赖。(3)将生成的两个dll,加上本身protobuf-net的dll一起加入到游戏工程,通过序列化dll里的序列化方法对消息进行处理。

  到这里,这个问题应该就算解决了。不过感觉步骤还是有点繁琐,这种机械化的工作就应该让机器做,所以接下来就是将上面的几个步骤,做成自动化批处理,每次编译工程时,自动执行。这样一来,也算完美解决了。

protobuf-net precompile的更多相关文章

  1. 解决protobuf不能直接在IOS上使用,利用protobuf-net在IOS上通讯

    ---------------------------------------------------------------------------------------------------- ...

  2. 在ios android设备上使用 Protobuf (使用dll方式)

    http://game.ceeger.com/forum/read.php?tid=13479 如果你的工程可以以.Net 2.0 subset模式运行,请看这个帖子中的方法. 地址:http://g ...

  3. 转一篇关于如何在Unity里使用Protobuf

    原帖地址: http://purdyjotut.blogspot.com/2013/10/using-protobuf-in-unity3d.html 先转过来,等时间合适了,再来收拾 Using P ...

  4. (转)在ios android设备上使用 Protobuf (使用dll方式)

    自:http://game.ceeger.com/forum/read.php?tid=13479 如果你的工程可以以.Net 2.0 subset模式运行,请看这个帖子中的方法. 地址:http:/ ...

  5. python通过protobuf实现rpc

    由于项目组现在用的rpc是基于google protobuf rpc协议实现的,所以花了点时间了解下protobuf rpc.rpc对于做分布式系统的人来说肯定不陌生,对于rpc不了解的童鞋可以自行g ...

  6. Protobuf使用规范分享

    一.Protobuf 的优点 Protobuf 有如 XML,不过它更小.更快.也更简单.它以高效的二进制方式存储,比 XML 小 3 到 10 倍,快 20 到 100 倍.你可以定义自己的数据结构 ...

  7. java netty socket库和自定义C#socket库利用protobuf进行通信完整实例

    之前的文章讲述了socket通信的一些基本知识,已经本人自定义的C#版本的socket.和java netty 库的二次封装,但是没有真正的发表测试用例. 本文只是为了讲解利用protobuf 进行C ...

  8. 在Wcf中应用ProtoBuf替代默认的序列化器

    Google的ProtoBuf序列化器性能的牛逼已经有目共睹了,可以把它应用到Socket通讯,队列,Wcf中,身为dotnet程序员一边期待着不久后Grpc对dotnet core的支持更期待着Wc ...

  9. protobuf的编译安装

    github地址:https://github.com/google/protobuf支持多种语言,有多个语言的版本,本文采用的是在centos7下编译源码进行安装. github上有详细的安装说明: ...

  10. 编译protobuf的jar文件

    1.准备工作 需要到github上下载相应的文件,地址https://github.com/google/protobuf/releases protobuf有很多不同语言的版本,因为我们需要的是ja ...

随机推荐

  1. Python操作远程数据库

    我的项目要往数据库中插入create_time和update_time,那就势必要引用现在的系统时间,经过大量的查找,终于发现往python是没有对应时间datetime的相关通配符的,那么我们要怎么 ...

  2. strong,weak, retain, assign的区别@property的参数

    strong,weak, retain, assign的区别@property的参数 先说经验 使用场合 copy:NSString,block, weak:UI控件,代理 strong:一般对象.自 ...

  3. System.err与System.out的区别

    大多数操作系统都有三个标准文件描述符:标准输入,标准输出,标准出错. 三个操作系统的文件描述符映射到编程语言的标准库中,往往加了一层包装,但是名字通常还是叫标准输入,标准输出,标准出错. 在其它语言中 ...

  4. Java 基础入门随笔(6) JavaSE版——数组操作

    1.数组 概念:同一种类型数据的集合.其实就是数组就是一个容器. 好处:可以自动给数组中的元素从0开始编号,方便操作这些元素. 格式: ①. 元素类型[] 数组名 = new 元素类型[元素个数或数组 ...

  5. SQL SERVER 2008 在某表中新增一列时失败

    背景:新增列语句如:“alter table 表名 add 列名 float default 0 with values”(用VS2010做网站,这句话是在C#代码里执行的) 报错提示: 警告: 已经 ...

  6. Linux终端常用快捷操作

    命令或文件名自动补全:在输入命令或文件名的前几个字母后,按Tab键,系统会自动补全或提示补全 上下箭头:使用上下箭头可以回溯之前的命令,增加命令的重用,减少输入工作量 !加之前输入过的命令的前几个字母 ...

  7. Java笔记——String、StringBuffer和StringBuilder类

    String类是不可变类,即一旦一个String对象被创建以后,包含在这个对象中的字符串序列是不可改变的,直至这个对象被销毁.   StringBuffer对象则代表一个字符序列可变的字符串,当一个S ...

  8. 2n皇后 - 回溯

    题目地址:http://www.51cpc.com/web/problem.php?id=1172 Summarize: 1. 递归回溯: 2. 先扫完一种皇后,再扫描另一种: 3. 循环输入: 4. ...

  9. 洛谷——P2801 教主的魔法(线段树or分块)

    P2801 教主的魔法 (1) 若第一个字母为“M”,则紧接着有三个数字L.R.W.表示对闭区间 [L, R] 内所有英雄的身高加上W. (2) 若第一个字母为“A”,则紧接着有三个数字L.R.C.询 ...

  10. 修改虚拟机中Linux的IP

    联网:ifup eth0 查看ip:ifconfig 点击编辑,选择NAT,子网ip修改第三字段为25,确定,重启linux后,会自动分配字段为25的ip 或者,也可以修改为自己想要的ip,如图:进入 ...