最近把以前做的老游戏拿出来,重新编到手机上来玩玩,然后就有了以下的经历。

那时的引擎还是Cocos2dx-2.x,iPhone5还是高档机型。现在的机器是这样的,iPhone6S Plus我自用,今年iPhone7S都要出来了,真是时光荏苒,岁月如梭。

拿出我的CooolPad大神F2,OK。iPhone6S Plus,OK。Ad-Hoc,安装OK,运行,崩了。最令开发人员抓狂的事情出现了,Debug版OK,Release版崩溃。

这里还是要感谢一下Xcode,Release版也是可以调试的这个事情。最近逛论坛,有位童鞋把Debug版没问题Release版崩溃的应用不断的提到AppStore,被退回来的几乎崩溃,然后有位跟帖的好心人告诉他,把Scheme里的Run改成Release就可以调试了。

崩溃点在这里

~CURLRaii() {
if (m_curl)
curl_easy_cleanup(m_curl);//崩溃在这里
/* free the linked list for header data */
if (m_headers)
curl_slist_free_all(m_headers);
}

的确,不用curl_easy_cleanup(m_curl)就不崩溃了,但显然这不是个好办法。

然后就是各种搜索,有个人给出了下面的方法

bool perform(int *responseCode) {
if (CURLE_OK != curl_easy_perform(m_curl))
return false;
long temp = ;//注意这里,用long类型去获得curl_easy_getinfo的信息
CURLcode code = curl_easy_getinfo(m_curl, CURLINFO_RESPONSE_CODE, &temp);
*responseCode = (int)temp;
if (code != CURLE_OK || *responseCode != )
return false; // Get some mor data. return true;
}

问题解决,显然这是C语言的老问题了,传指针的时候一定要类型匹配。以前没问题是因为32位平台上long和int是一样的,包括我现在的酷派大神。其实如果是原来的工程也应该是没问题的,因为那时的Cocos2dx中的curl是32位的静态库,但是现在AppStore要求必须要提供64位的版本,所以这个问题是无法掩盖了。现在的问题就是,这个崩溃的锅,应该由谁来背?

表面来看,这个锅是Cocos2dx的,君不见curl的接口描述是这样的,谁让你传int进去的?

/*
* NAME curl_easy_getinfo()
*
* DESCRIPTION
*
* Request internal information from the curl session with this function. The
* third argument MUST be a pointer to a long, a pointer to a char * or a
* pointer to a double (as the documentation describes elsewhere). The data
* pointed to will be filled in accordingly and can be relied upon only if the
* function returns CURLE_OK. This function is intended to get used *AFTER* a
* performed transfer, all results from this function are undefined until the
* transfer is completed.
*/
CURL_EXTERN CURLcode
curl_easy_getinfo(CURL * curl , CURLINFO info, ... ) ;

但请不要忘记,这是C语言,强类型的语言,出现这种因为类型不匹配引起的崩溃,责任可不全在调用者身上,我连个警告都没看到,谁知道你是怎么运作的?下面我们来看一下这个没有警告的“泛型”是怎么运作的。

首先,curl强调了这个函数有并且只有3个参数

/* This preprocessor magic that replaces a call with the exact same call is
only done to make sure application authors pass exactly three arguments
to these functions. */
#define curl_easy_setopt(handle, opt, param) curl_easy_setopt(handle,opt,param)
#define curl_easy_getinfo(handle, info, arg) curl_easy_getinfo(handle,info,arg)
#define curl_share_setopt(share, opt, param) curl_share_setopt(share,opt,param)
#define curl_multi_setopt(handle, opt, param) curl_multi_setopt(handle,opt,param)

然后利用变长参数不检查类型的特点完成了这个戏法,本质上这和scanf是一样的,当初栽在这个函数上的童鞋们这回应该明白崩溃的原因了吧。

我很少用C语言的原因就是C的基础设施很少,C的奇技淫巧很多。虽然C++的坑更多,但是在不踩雷的情况下,还是能基本完成任务的。在C的领域内,你要是不会点此类的技巧,你几乎什么也做不了。

这也说明了,片面的强调编程语言应该是强类型还是弱类型都是不对的,C语言千方百计的要泛型,现在的脚本语言却逐渐开始强调类型声明。

最后,这个问题在C++中是可以避免的,也不用着上面的“技巧”。当然,我声明成long*或者long&,你非得传int就不能怨我了。

从解决Cocos2dx-2.x arm64 Crash 来看C的奇技淫巧的更多相关文章

  1. 解决cocos2dx在Xcode中运行时报:convert: iCCP: known incorrect sRGB profile 的问题

    解决cocos2dx在Xcode中运行时报:convert: iCCP: known incorrect sRGB profile 的问题 本文的实践来源是参照了两个帖子完成的: http://dis ...

  2. linux下开发,解决cocos2d-x中编译出现的一个小问题, undefined reference to symbol 'pthread_create@@GLIBC_2.2.5'

    解决cocos2d-x中编译出现的一个小问题 对于cocos2d-x 2.×中编译中,若头文件里引入了#include "cocos-ext.h",在进行C++编译的时候会遇到例如 ...

  3. 解决cocos2d-X 2.0版本后创建的Android项目提示org.cocos2dx.lib.Cocos2dxActivity找不到问题

    原地址: http://blog.163.com/zhoulong19880518@126/blog/static/6070970220132511558143/ 解决方法:    复制 ***\co ...

  4. 【Cocos2d-x游戏开发】解决Cocos2d-x中文乱码的三种方法

    众所周知,Cocos2d-x是一款不错的开源引擎,但是在Cocos2d-x中直接使用中文是无法正确显示的.比如下面的情况: 解决这个问题常用的有三种方法:1.通过转换为UTF-8编码来显示.2.使用i ...

  5. 解决cocos2dx调用removeFromParent后报错问题

    原因:cocos2dx的bug 解决办法: 放到action中,前面添加一个DelayTime延迟,代码如下 this->runAction(Sequence::create(DelayTime ...

  6. [Windows] 解决 VLC Media Player 的 Crash Reporting 消息弹窗

    运行环境:Windows 8.1 (64bits), VLC Media Player 2.1.3 异常描述:首次启动VLC播放影音文件时,一切正常.此后每次启动VLC都弹出"VLC Cra ...

  7. Mac OS X 10.9下解决cocos2d-x在Xcode4.6.x的模板不显示问题

    最近将iMac 升级到10.9了,奇怪的事情发生了,cocos2d-x的模板不见了,鼓捣了半天发现问题所在 打开xcode新建工程却找不到cocos2d-x的模板. 经过在网上的苦苦搜寻和试验后,找到 ...

  8. 解决 Cocos2d-x 3.2 error C1041: 无法打开程序数据库vc120.pdb

    单个项目解决方案 解决方案是为项目添加 /FS (Force Synchronous PDB Writes) 编译选项,具体位置在: 一劳永逸的解决方案 直接修改cocos的项目模板templates ...

  9. 解决 Cocos2d-x 中 Android.mk 手动添加源文件

    转自:http://blog.csdn.net/ypfsoul/article/details/8909178 Makefile Android.mk 引发的思索 在我们编写 Android 平台 c ...

随机推荐

  1. IP命令介绍

    ip指令可以显示或操作路由.网络设备.设置路由策略和通道 1.语法 ip [选项]  Object  COMMAND [help] Object对象可以是: link  网络设备.addr 设备的协议 ...

  2. layui表格自动对齐

    正常情况table应该是这样展示的 但是却展示成了这样 格子没对齐,找了半天原因发现是在table.render中的cols参数多了一个"," 不细心一点真看不出来 正常结构应是 ...

  3. Java反射的应用 --- 内省

    一.基础概念 内省(Introspector) 是Java 语言对 JavaBean 类属性.事件的一种缺省处理方法.Java JDK中提供了一套 API 用来访问某个属性的 getter/sette ...

  4. tomcat启动不了的问题

    tomcat启动的几个问题 1.端口冲突 2.非端口冲突,需要加入配置host文件 日志文件: 解决办法:https://blog.csdn.net/u012949658/article/detail ...

  5. Jenkins 2 如何使用 PowerShell 以及自定 build fail (指定 exit code)

    Jenkins 除了用來做為 CI(持續性整合) 工具外,也可以與其他 plugin 配合達成其他目的(e.g.IIS restart.檔案壓縮備份-),今天就來看看可以怎麼與 PowerShell ...

  6. Nginx笔记总结十七:nginx生成缩略图配置(http_image_filter_module)

    编译: ./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_realip_module-- ...

  7. leetcode笔记——35.搜索插入位置 - CrowFea

    0.问题描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引.如果目标值不存在于数组中,返回它将会被按顺序插入的位置. 你可以假设数组中无重复元素. 示例 1: 12 输入: [1,3 ...

  8. Flask向模板中JS传值简便方式

    后台传值: return render_template('statistics/numberofuserlogin/login_number.html', result_json = json.du ...

  9. centos7开启ntp并同步时间到指定时区

    前提:近期公司都是使用的直接对外的云服务器,在登上服务器后用date命令查看新服务器的时间,发现并不是标准时间,于是需要做时间同步.我这里讲的是能连接外网的情况下,在服务器不多的情况下是否此方法,大型 ...

  10. java的23种设计模式之建造者模式

    场景和本质 场景 本质 案例 原理 应用场景 场景和本质 场景 我们要建造一个复杂的产品.比如:神州飞船,Iphone.这个复杂的产品的创建.有这样一个问题需要处理:装配这些子组件是不是有个步骤问题? ...