diegor at December 22nd, 2011 15:27 — #1
After the latest Cocos changes where dynamic cast were introduced, I am having the following issue:
class TouchSprite : public CCSprite, public CCTargetedTouchDelegate
and in the onEnter function I am doing:
After tracing, I found that bool CCTouchHandler::initWithDelegate fails in
because the dynamic cast fails and returns NULL.
The code works fine when compiled using Xcode in iOS, but fails in Android. Any ideas?
\* Update: The touchesTest demo (which my code snippet is based on), crashes the same way in Android (runs fine in iPhone), I hope
this makes it easier for the team to find the issue.
zhangxm at December 25th, 2011 14:42 — #2
Yes, it crashed in (dynamic_cast(pDelegate))->retain().
#926 is created for it.
zhangxm at December 26th, 2011 14:37 — #3
I do the following test:
CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this, 0, true)
It also crashed at CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this, 0, true).
class Paddle : public CCSprite, public CCTargetedTouchDelegate
class Paddle : public CCTargetedTouchDelegate, public CCSprite
It also crashed.
CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this, 0, true) is called in other tests, but they are ok.
The difference is that Paddle inherits CCSprite, not CCLayer.
I don’t know why.
diegor at December 27th, 2011 02:08 — #4
Thanks for taking a look. The problem is that the way the paddle demo works is the cleanest way to track sprites touches.
Otherwise I’ll have to pass all the touch handling to the scene object which is not a clen way to handle this.
Do we have any C++ wizards in the forums who can help?
zhangxm at December 27th, 2011 14:49 — #5
In MenuTest.h, MenuLayer1 also invoke CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this, 0, true), it works ok.
class MenuLayer1 : public CCLayer
class MenuLayer1 : public CCLayer, public CCTextureProtocol
to make it inherits from multiple classes, it also works ok.
Both CCLayer and CCSprite inherit from multiple classes, and both of them inherit from CCNode.
So I think it is the matter with the content of CCSprite.
But I don’t know why.
It is so strange, because it works ok in Paddle.cpp, but fails in CCTouchHandler.cpp.
weeds at January 30th, 2012 14:21 — #6
The problem is still there with CCKeypadDelegate.
I’m not sure on the perfect solution though.
In general rtti does not work over module boundaries: http://gcc.gnu.org/faq.html\#dso (at least not in a safe and portable way)
I guess the reason why the layer approach works is, that CCKeypadDelegate (and CCTouchDelegate) are extended by CCLayer directly (i.e. library code).
While in the Paddle example the delegate is extendend by client code (i.e. in a different module).
So I guess there may be three solutions to this problem:
- compile game and library code into one single shared library (or statically link cocos2d and cocosdenshion)
- manually load the libraries using dlopen with the RTLD_GLOBAL flag (I havn’t seen a way to add flags to the java call. Also this solution probably isn’t really future-proof in case the internal file hierarchy changes)
- remove rtti from the library
zhangxm at January 30th, 2012 21:34 — #7
We can not remove rtti, because we have to use multiple inherit.
I think the best way is to build cocos2dx into a static library.