从解决Cocos2dx-2.x arm64 Crash 来看C的奇技淫巧

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

那时的引擎还是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 = 0;//注意这里,用long类型去获得curl_easy_getinfo的信息
    CURLcode code = curl_easy_getinfo(m_curl, CURLINFO_RESPONSE_CODE, &temp);
    *responseCode = (int)temp;
    if (code != CURLE_OK || *responseCode != 200)
        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就不能怨我了。

时间: 2024-10-03 03:11:44

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

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

原地址: http://blog.163.com/[email protected]/blog/static/6070970220132511558143/ 解决方法:    复制 ***\cocos2dx\platform\android\java\src\ (***为cocos2d-x更目录) 到你android项目中的src文件夹中这样就又有一个麻烦问题,是不是每次创建都要复制呢,答案当然是否定的,来看一劳永逸的方法,定位 (cocos2d-x根目录)\template\android\,

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

解决cocos2d-x中编译出现的一个小问题 对于cocos2d-x 2.×中编译中,若头文件里引入了#include "cocos-ext.h",在进行C++编译的时候会遇到例如以下错误: undefined reference to symbol '[email protected]@GLIBC_2.2.5'/lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from command li

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

运行环境:Windows 8.1 (64bits), VLC Media Player 2.1.3 异常描述:首次启动VLC播放影音文件时,一切正常.此后每次启动VLC都弹出"VLC Crash Reporting",点击"Yes"或"No"后,VLC会开始播放文件,一切正常. 解决方法:VLC安装完毕后,因为"%AppData%"中没有crashdump文件,VLC正常启动.VLC正常启动后,在"%AppData%

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

单个项目解决方案 解决方案是为项目添加 /FS (Force Synchronous PDB Writes) 编译选项,具体位置在: 一劳永逸的解决方案 直接修改cocos的项目模板templates\cpp-template-default\proj.win32\HelloCpp.vcxproj为: <?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build

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

众所周知,Cocos2d-x是一款不错的开源引擎,但是在Cocos2d-x中直接使用中文是无法正确显示的.比如下面的情况: 解决这个问题常用的有三种方法:1.通过转换为UTF-8编码来显示.2.使用iconv库来解决.3.使用解析xml或者json文件来解决.这里推荐使用第三种方法来解决,因为比较简单方便,还能支持I18N国际化.下面我们来一一详细了解一下每种解决方案的具体实现: 一.通过转换为UTF-8编码的方式显示出来,建立一个方法用于转换中文到对应的UTF-8编码,具体代码如下: 1 ch

解决cocos2dx调用removeFromParent后报错问题

原因:cocos2dx的bug 解决办法: 放到action中,前面添加一个DelayTime延迟,代码如下 this->runAction(Sequence::create(DelayTime::create(0.1f),CallFuncN::create([&](Node* pNode){pNode->removeFromParent();}),NULL));

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

本文的实践来源是参照了两个帖子完成的: http://discuss.cocos2d-x.org/t/cocos2d-x-3-0-and-libpng/12451. http://www.myexception.cn/image/462530.html, 感谢以上作者的分享... 以前每次运行cocos2dx 的程序时总是报警告:convert: iCCP: known incorrect sRGB profile, 今天来解决一下... 要解决这个问题需要在终端(Mac)运行 ImageMag

解决cocos2dx在VS2012中文版环境下不支持中文的问题

首先要明确的一点是:cocos2dx是支持中文的.因为其编码格式为UTF-8(无签名)——这只是我在网上找到的结论,并非从官方获取,因此不能十分确定,不过应该无误. 那么,为什么在VS2012环境下,cocos2dx不能正确显示中文呢? 这是因为二者编码格式不一致.VS2012中文版的默认编码格式为GB2312-80(我不确定英文版的格式如何,总之应该不是UTF-8).在GB2312-80编码格式中,一个中文占2个字节,而在UTF-8格式中,一个中文占3个字节.这就势必会出现乱码. 找到了原因,

解决 Ubuntu Software (Software Center) Crash 问题

问题描述: no application data found 解决方式: sudo apt purge gnome-software ubuntu-software sudo apt autoremove sudo apt install gnome-software ubuntu-software Starting Ubuntu Software on 16.04 cause an 'internal error'. Reinstalling it totally fixed it. It