Cocos2dx 2.x is a bug in the android version of CCLabelTTF.
In android, cocos2dx uses Paint to generate images and display them in CCLabelTTF. The specific code is in java Cocos2dxBitmap, after the code is generated, A jni function is called to send the result to the cpp layer. The cpp layer exchanges data with the java layer based on a static variable. The details are as follows:
BitmapDC &dc = sharedBitmapDC(); CC_BREAK_IF(! dc.getBitmapFromJava(pText, nWidth, nHeight, eAlignMask, pFontName, nSize)); // assign the dc.m_pData to m_pData in order to save time m_pData = dc.m_pData; CC_BREAK_IF(! m_pData);
There is a problem here that sharedBitmapDC is always shared, and its dc. m_pData always stores the last data. If the java Layer fails to call the data for some reason, the cpp layer will continue to get the previous data, however, the cpp layer is responsible for free data, so double free may cause program crash. We encountered this problem in practice. The collapsed stack told us that there was a problem in the CCImage analysis structure.
CCImage::~CCImage(){ CC_SAFE_DELETE_ARRAY(m_pData);#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) CC_SAFE_DELETE(m_ft);#endif}
However, it is okay to simply look at the CCImage code, and if there is a problem here, it will be too much trouble. After the final check, confirm that the cpp part may hide the bug, and modify the above CCImage as follows:
BitmapDC &dc = sharedBitmapDC(); CC_BREAK_IF(! dc.getBitmapFromJava(pText, nWidth, nHeight, eAlignMask, pFontName, nSize)); // assign the dc.m_pData to m_pData in order to save time m_pData = dc.m_pData; dc.m_pData = NULL; CC_BREAK_IF(! m_pData);
In this way, the cpp layer will certainly not have double free, so we will test again. At this time, we will find that the java layer throws an exception. The previous exception was not printed because the program exits. Trace the java layer and find out the specific reason:
After setContentSize, the java layer determines Based on ContentSize that the font cannot be put in, so it considers that the height of the created Bitmap is 0, while Bitmap does not allow the creation of a height of 0, so it is abnormal. The solution is to display it in at least one row and one column, so that we can see that the display knows what went wrong, rather than directly crashing.
From this issue, we once again confirm the programming habits of fail early and fail merge. Otherwise, a simple problem becomes a complicated problem.