从cocos2dx源代码看android和iOS跨平台那些事
cocos2dx一个跨移动(平板)平台的游戏引擎,支持2d和3d,基于c/c++,网上介绍多在此不详叙。
我们本篇关心的是跨平台那些事,自然而然就找到platform目录。好家伙,支持的操作平台还真不少,最吸引我们关注的可能就是字母顺序排列的头二个平台,android和apple。然后顺带会看一看winrt和linux。platform这个目录,物如其名,就是一些使用到平台服务的东西(封装)。platform目录下各平台子目录封装的平台服务都大同小异,唯android目录特殊还多了jni和java两个目录。因为在android平台下做应用,用c/c++的话还跨了语言。至于iOS,c/c++和oc混搭是很自然的事。所以我们来看android平台的跨语言那些事。
cocos/platform/android/jni,不用解释,就是java native interface。包含了从java到c/c++和从c/c++到java的调用协定。
这个目录最主要的就是JniHelper相关的头和源两个文件了。它主要负责帮助c/c++代码层完成对java代码层的静态方法的调用。而其它代码文件则是,特定为某个java类提供c/c++到java静态方法调用帮助,或是java到c/c++函数调用的帮助。
所以这个目录主要用来帮助c/c++代码调用java代码,而c/c++跨平台为java提供的功能(或服务)的函数,一般来说都分散到了具体模块的目录里,当需要支持跨平台的代码时,会将平台相关代码,写到如某个类的`-android.cpp`文件去。
另一个目录就是cocos/platform/android/java。没错就是java代码的目录。里面包含了一些专为cocos引擎层,也就是为让c/c++代码层使用到java库,或用java库实现功能的组件。可以通过java代码使用到android平台提供的服务。对于apple平台(iOS和mac)来说,c/c++代码与oc类混合使用是很自然的事;而winrt平台,平台提供的服务自然就是c/c++,或许以COM的形式;至于linux,第三方库都是c/c++库。因此除android以外的其它平台的子目录,并没有做太多的周折(相对于android来说)。
下面请看一下这样的比较:
// jni
jclass _clazz = (jclass) env->CallObjectMethod(jobj, loadclassMethod_ID, jstrClassName);
jclass _clazz = env->FindClass(_cstrClassName);
// iOS
Class _clazz = NSClassFromNSString(_nsstrClassName);
Class _clazz = [ClassName class];
// jni
jmethodID methodID = env->GetMethodID(_clazz, cstrMethodName, cstrParamCode);
// iOS
SEL _selector = NSSelectorFromString(_nsstrSELName);
IMP imp = class_getMethodImplementation(_clazz, _selector);
// jni
env->CallObjectMethod(jobj, methodID /**, (jobject*)arg1, ... */);
// iOS
objc_msgSend(obj, sel /**, arg1, arg2, ... */);
可以看到java和oc之间还有共通,现在从java看oc,还是从oc看java,都不会感到完全的陌生,反而有几分亲近。
有一点要注意的是,java的类名是全路径的,在代码中以点引用的方式对包引用,在名字中则以'/'为节点分隔的路径。java将方法拆分开方法名和原型描述。原型描述包含参数列表以及返回类型,参数列表以'()'包含放在前面,后面才是返回类型。对于java对象类型的描述包含在'L;'配对之中,java对象类型自然是类名的全路径了。'['表示的是数组。
jni从java调用c/c++代码也就可能这么一回事。java中只有类静态方法和成员方法,所以java要调用c/c++函数,就必须在java层有对应的方法入口(或者说可以让java代码调用的等价物,methodID),这样就将成员方法声明为native。从上面c/c++调用java的函数CallObjectMethod可以看出,java调用成员方法时也是根据methodID找对应的代码入口,jni生成的c/c++函数声明也就是java中对应声明为native的成员方法的methodID的映射。
当跨越jni时,相应也产生了损耗,其中原因只能去看jvm的代码了。在这里我只是试着猜想,可能c/c++函数和methodID不是直接映射,中间可能要做路由还是适配,或者是还有几层的处理,构建跨语言的栈帧环境等。另外可能就是,c/c++函数不是字节码指令的东西,不利于虚拟机对代码的优化,就好像处理器在分支预测失败的时候,要清空预装载的指令重新装入指令分支。
从cocos2dx源代码看android和iOS跨平台那些事的更多相关文章
- 【从源代码看Android】02MessageQueue的epoll原型
版权声明:本文为博主原创文章,欢迎转载.请注明原文链接 https://blog.csdn.net/ashqal/article/details/31772697 1 开头 上一讲讲到Looper,大 ...
- 通过微信Android和iOS版,看两大系统的差异
由于设计师或者产品经理使用的移动设备大部分是iPhone,所以在做设计时,容易忽略Android和iOS的差异,按照自己的使用习惯进行设计,导致大部分设计师或产品经理做出的设计都是基于iOS规范或习惯 ...
- Cocos2d-x在win32,android和IOS下的文件读写问题
最近在学习和使用Cocos2d-x框架,虽然说的是跨平台,但是在用VS进行开发,然后移植到android或IOS下,也可能会出现各种问题,需要做细微的调整. 例如我在做文件读写操作的时候,很可能在wi ...
- Mac下配置cocos2d-x开发环境(android和ios)
一.下载cocos2d-x http://cocos2d-x.org/projects/cocos2d-x/wiki/Download cocos2d-x-2.1.4.zip @ June.18, 2 ...
- cocos2d-x系列 Mac下配置cocos2d-x开发环境(android和ios)
一.下载cocos2d-x http://cocos2d-x.org/projects/cocos2d-x/wiki/Download cocos2d-x-2.1.4.zip @ June.18, 2 ...
- Cocos2d-x 3.x 头像选择,本地相册图片+图片编辑(Android、IOS双平台)
大连游戏产业不是很发达,最后,选择一个应用程序外包公司.积累的工作和学习过程中的一点业余生活微信体验,我想分享的游戏小朋友的爱. 在应用开发过程中会经常实用户上传头像的功能,在网上找了N多资料发现没有 ...
- 用Flutter开发的跨平台项目,完美运行在Android和IOS上,Material简洁风格,包括启动页、引导页、注册、登录、首页、体系、公众号、导航、项目,还有漂亮的妹子图库,运行极度流畅,结构清晰,代码规范,值得拥有
Flutter学习资源汇总持续更新中...... Flutter官方网站 Flutter中文网 wendux的Flutter实战 Flutter官方exampleflutter_gallery 阿里巴 ...
- 使用多字节字符集的跨平台(PC、Android、IOS、WP)编码/解码方法
随着移动端的发展,跨平台已成为通讯架构设计的重要考虑因素,PC.Android.IOS.WP等跨多平台间的数据通讯,必然要解决字符编码/解码的问题. 多字节字符集MBCS不是跨平台的首选字符集,面向跨 ...
- GitHub Android 最火开源项目Top20 GitHub 上的开源项目不胜枚举,越来越多的开源项目正在迁移到GitHub平台上。基于不要重复造轮子的原则,了解当下比较流行的Android与iOS开源项目很是必要。利用这些项目,有时能够让你达到事半功倍的效果。
1. ActionBarSherlock(推荐) ActionBarSherlock应该算得上是GitHub上最火的Android开源项目了,它是一个独立的库,通过一个API和主题,开发者就可以很方便 ...
随机推荐
- pycharm中常见错误提示
1.类中定义函方法 PyCharm 提示Method xxx may be 'static': 原因:该方法不涉及对该类属性的操作,编译器建议声明为@staticmethod
- vmware14安装centos7的步骤(图文详解)
一.centos的安装 centos分为桌面版和黑屏版(命令行版):在这里我使用的是命令行版. 这里选择安装程序光盘映像文件,文件就是centos7的iso文件. 虚拟机的名称和位置自行设置; 虚拟机 ...
- 工厂模式在mvc模型中的应用
在web开发中我们常用mvc模式进行web应用的开发 当应用进入service 层的时候我们根据不同的业务多逻辑进行处理 当有数据进入controller的时候 public class Virtua ...
- 如何在 GitHub 的项目中创建一个分支呢?
如何在 GitHub 的项目中创建一个分支呢? 其实很简单啦,直接点击 Branch,然后在弹出的文本框中添加自己的 Branch Name 然后点击蓝色的Create branch就可以了,这样一来 ...
- 面试 LockSupport.park()会释放锁资源吗?
(手机横屏看源码更方便) 引子 大家知道,我最近在招人,今天遇到个同学,他的源码看过一些,然后我就开始了AQS连环问. 我:说说AQS的大致流程? 他:AQS包含一个状态变量,一个同步队列--bala ...
- Solr分片机制以及Solrcloud搭建及分片操作
Solr分片描述 分片是集合的逻辑分区,包含集合中文档的子集,这样集合中的每个文档都正好包含在一个分片中.集合中包含每个文档的分片取决于集合的整体"分片"策略. 当您的集合对于一个 ...
- PSTAT 115 Homework4 课业解析
PSTAT 115 Homework4 课业解析 题意: 蒙特卡洛采样之拒绝采样 解析: 给定一个概率分布p(z)=p~(z)/Zp,p~(z)已知,Zp为归一化常数,为未知数.对该分布进行拒绝采样, ...
- 两行代码玩转SUMO!
两行代码玩转SUMO! 这篇博客很简单,但是内容很丰富 如何生成如下所示的研究型路网结构? 只需要打开ubuntu终端输入如下代码即可,grid.number代表路口数量,grid.length代表路 ...
- Java网络编程(一)Socket套接字
一.基础知识 1.TCP:传输控制协议. 2.UDP:用户数据报协议. 二.IP地址封装 1.InetAddress类的常用方法 getLocalHost() 返回本地主机的InetAddress对象 ...
- unity 开启外部摄像头
在unity中建立一个image作为摄像头显示画面,然后通过命令render到image上即可. public WebCamTexture webTex; public string deviceNa ...